모델링의 경우, 우선 생성/수정/삭제에 대한 이력을 저장하기 위해
core
라는 앱을 생성 후 TimeStampModel
을 만들었습니다
python manage.py startapp core
'''
core/models.py
'''
from django.db import models
class TimeStampModel(models.Model) :
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
deleted_at = models.DateTimeField(null=True)
class Meta :
abstract = True
updated_at
, delete_at
에 auto_now=True
를 하려고 했는데
그렇게 되면 데이터 생성 시, 저 두 컬럼에 생성시간이 들어가버리게 됩니다.
그래서 null=True
를 설정하여 데이터 생성시 null
값이 되게 했으며,
views.py
에서 수정/삭제에 대한 로직을 작성할 때 날짜를 기입하는 걸 기획했습니다.
유저 정보를 저장할 테이블을 만들기 위해 users
앱을 생성했습니다.
python manage.py startapp users
'''
users/models.py
'''
from django.db import models
from core.models import TimeStampModel
class Role(TimeStampModel) :
role = models.CharField(max_length=20)
class Meta :
db_table = 'roles'
class User(TimeStampModel) :
role = models.ForeignKey(Role, null=True, on_delete=models.SET_NULL)
email = models.EmailField(unique=True, max_length=40)
password = models.CharField(max_length=500)
class Meta :
db_table = 'users'
Zara를 회원가입하려고 보면 이름도 필수입력인데, 굳이 컬럼에 추가하지 않았습니다.
이름이야 동명이인도 많고, 데이터 식별에 큰 비중이 있을 것 같지 않기 때문입니다.
또한, 항목체크하는 부분은 충분히 프론트엔드에서 통제 가능한 부분이기 때문에
그 부분도 생략했습니다.
Role
의 경우, 관리자용 페이지를 알 수는 없지만 추후의 확장성을 고려한 것과 동시에
상품 추가하려면 관리자의 권한이 필요하여 만들게 되었습니다.
다만, User
에서 참조를 할 때 on_delete
옵션에 대해 고민이 많았는데
종속시켜 삭제시키는 건 굉장히 위험하기 때문에 일단 null
이 되게 설정 후
추후에 관리자를 이용해 바꾸도록 코드 작성할 예정입니다.
마지막으로, email
에 unique=True
를 설정하여 무결성의 원칙을 지키도록 했습니다.
import json
import bcrypt
import jwt
from django.db import IntegrityError
from django.http import JsonResponse
from django.views import View
from users.models import (
Role,
User
)
class SignUpView(View) :
def post(self, request) :
try :
data = json.loads(request.body)
email = data['email']
password = data['password']
role_id = int(data['role_id'])
password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
role = Role.objects.get(id=role_id)
User.objects.create(
email = email,
password = password,
role = role
)
return JsonResponse({'message' : 'CREATE_USER'}, status=201)
except KeyError :
return JsonResponse({'message' : 'KEY_ERROR'}, status=400)
except IntegrityError :
return JsonResponse({'message' : 'INTEGRITY_ERROR'}, status=400)
except Role.DoesNotExist :
return JsonResponse({'message' : 'ROLE_DOES_NOT_EXIST'}, status=400)
role_id
의 경우 2
or "2"
와 같이 입력할 수 있어서 int
로 변환하는 걸 설정해줬어야 했습니다.
비밀번호의 경우, 암호화가 진행됩니다.
role_id
를 통해 객체를 가져오는 코드가 가장 봐야할 부분인데
원래 내가 받은 role_id
값이 Role
에 존재하지 않는다면 아래와 같이 작성했었습니다.
if not Role.objects.filter(id=role_id).exists() :
return JsonResponse({'message' : 'ROLE_DOES_NOT_EXIST'}, status=400)
하지만 아래 예외처리에서 Role.DoesNotExist
를 설정했기 때문에
굳이 조건문을 안써줘도 해당하는 객체를 못 가져온다면 예외처리문으로 가게 됩니다.
그리고 email
의 경우도 회원가입하려는데 이미 존재한다면
if User.objects.filter(email=email).exists() :
return JsonResponse({'message' : 'ALREADY_EXIST'}, status=400)
같이 작성해줘야하지만, 아래 예외처리에서 IntegrityError
를 설정했기 때문에
굳이 조건문을 안써줘도 이미 존재하는 메일이라면 예외처리문으로 가게 됩니다.
다음 포스팅은 로그인입니다.