Framework/Django

장고 모델과 사용자 모델 비교, 사용자 모델 업그레이드하기

JM Lee 2023. 4. 4. 11:54
728x90

스파르타 코딩클럽 참조.

왼쪽이 장고 기본 제공 테이블, 오른쪽은 사용자가 만든 테이블이다.

그만큼 장고 테이블 내용이 많기 때문에 사실 내 테이블이 필요한가? 싶겠지만

내 테이블에는 'bio'가 있다. 결국 장고에 없는 것도 존재하다는 건데,

그렇다면 이것을 어떻게 합쳐서 업그레이드할까?


사용자 모델 업그레이드하기

모델 업그레이드 목적으로 user/model.py에 들어갔다.

다음과 같이 class의 상속 내용을 먼저 이해하고 수정해보자.

#user/models.py
from django.db import models


# Create your models here.
class UserModel(models.Model): # UserModel 클래스를 적용하면 models.Model의 기능을 사용할 수 있다.
    class Meta:
        db_table = "my_user" # 내 테이블 이름이 my_user였음 좋겠다.

    username = models.CharField(max_length=20, null=False)
    password = models.CharField(max_length=256, null=False)
    bio = models.CharField(max_length=256, default='')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

원래 파일은 우리가 만든 my_user 테이블에서 적용했는데,

이제 장고의 기본 파일을 가져오기로 했다.

수정하면,

#user/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.
class UserModel(AbstractUser):
    # 장고에서 제공하는 기본 MODEL을 사용하겠다.
    class Meta:
        db_table = "my_user" # 내 테이블 이름이 my_user였음 좋겠다.

    bio = models.CharField(max_length=256, default='')
    # bio만 장고에 없으므로 살려둘 것

다음과 같이 나타나게 된다.

그럼 사용환경이 바뀌기 때문에 settings.py에 들어가서

# mySpartaSns/settings.py
AUTH_USER_MODEL = 'user.UserModel'

를 추가해주면 된다


사용자 모델을 데이터베이스에 적용하기

이거 앞에서 수도 없이 한 python manage.py makemigrations와 python manage.py migrate!

실행해주면 데이터베이스가 다음과 같이 업그레이드 됨을 알 수 있다!

계속 반복작업하니까 이제 덜 어려워졌다. 이 부분만..!


받은 데이터베이스를 적용하기

user/views.py를 손 댈 시간이다.

먼저 사용자가 데이터베이스 안에 있는지 검사하는 함수를 작성한다.

from django.contrib.auth import get_user_model

그 다음, 기존 user의 잔재를 지우고 업그레이드가 적용되게끔 코드를 작성하는데,

get method 같은 건 바꿀 내용이 없으니 넘어가고 POST method에서 비번이 일치하는 조건문만 손 대자.

def sign_up_view(request):
if request.method == 'GET': # GET 메서드로 요청이 들어 올 경우(되돌리기)
return render(request, 'user/signup.html') # 화면 보여주기
elif request.method == 'POST': # POST 메서드로 요청이 들어 올 경우(실질적 함수 목적)
username = request.POST.get('username', None)
password = request.POST.get('password', None)
password2 = request.POST.get('password2', None)
bio = request.POST.get('bio', None)

if password != password2: # 비번이 일치하지 않으면 요청을 무시해야겠지?
return render(request, 'user/signup.html') # get 요청과 마찬가지로 그냥 화면 보여주기로 끝
else:
exist_user = get_user_model().objects.filter(username=username) #기존 동일한 닉이 존재할 경우 exist_user DB에 넣지 않기
if exist_user:
return render(request, 'user/signup.html') # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움
else:
UserModel.objects.create_user(username=username, password=password, bio=bio)# 동일 닉이 없을 경우 DB에 저장하는 코드
#저장 됐으면 로그인 페이지를 보여줘야겠지?
#redirect 함수를 위에도 적고 아래 반환값에도 적어서 돌아가게끔 하자
return redirect('/sign-in')

이대로 해서 클라이언트 실현 후, 회원가입에 필요한 정보등록을 모두 마쳤다.

다른 건 모두 같지만 데이터베이스에 어떻게 변화가 이루어졌는지 볼까?

저번과는 다른 옵션이 많이 생겼다는 것을 확인할 수 있었다!!

아직 이것들을 등록하는 장치는 만들지 않았기 때문에 빈 칸이 많다.

앞으로 이것들도 채워봐야 한다.


비밀번호 보안 문제 해결

문제가 있다.

동그라미 친 부분은 어떻게 해결하면 좋을까?

지금 코드대로라면 우리는 인코딩된 패스워드와 내가 입력한 패스워드를 비교하게 되는데, 당연히 틀리게 된다.

이것을 수정하기 위해 아래와 같이 sign_in_view 함수의 코드를 수정해주었다.

def sign_in_view(request):
if request.method == 'POST':
username = request.POST.get('username', None)
password = request.POST.get('password', None)

me = auth.authenticate(request, username=username, password=password)
if me is not None:
# 사용자가 비어있지 않은 경우
auth.login(request, me) # 내 정보를 넣어서 로그인!
return HttpResponse(me.username)
else:
return redirect('/sign-in')
# 다시 로그인 창 이동, 틀렸으니 다시 도전!