이번에는 Instagram Clone을 하면서 처음으로 만들어 본 Sign up View를 만들고 복습할 겸 적어보려고 합니다!
처음 프로젝트를 시작하고 나서 해야 될 기본 설정들을 마치고 모델부터 작성하기로 했다
중간에 모델을 변경하게 되면 migrate문제가 있을 수 있기 때문에 최대한 넣을 수 있는 부분은 생각나는 대로 전부 포함시켜서 작성해 보았다
class User(models.Model):
name = models.CharField(max_length=50)
nickname = models.CharField(max_length=50)
email = models.EmailField(unique=True)
phone_number = models.CharField(max_length=20, unique=True)
password = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
기본적인 이름, 닉네임, 이메일, 휴대폰 번호, 비밀번호를 추가하고 계정이 만들어진 날짜 및 수정된 날짜까지 포함하여 모델링을 진행하였다
처음 프로토타입은 단순히 DB에 정보를 넣는 정도로만 진행 했었고 추후에 수정을 거쳐서 완성하게 되었다!
class SignupView(View):
def post(self, request):
data = json.loads(request.body)
try:
if not validate_email(data['email']):
return JsonResponse({'MESSAGE':'INVALID_EMAIL'}, status = 400)
if not validate_password(data['password']):
return JsonResponse({'MESSAGE':'INVALID_PASSWORD'}, status = 400)
if not validate_name(data['name']):
return JsonResponse({'MESSAGE':'INVALID_NAME'}, status = 400)
if not validate_phone_number(data['phone_number']):
return JsonResponse({'MESSAGE':'INVALID_PHONE_NUMBER'}, status = 400)
encoded_password = bcrypt.hashpw(
data['password'].encode('utf-8'),
bcrypt.gensalt()
)
User.objects.create(
name = data['name'],
nickname = data['nickname'],
email = data['email'],
phone_number = data['phone_number'],
password = encoded_password.decode('utf-8'),
)
return JsonResponse({'MESSAGE':'SUCCESS'}, status=201)
except KeyError:
return JsonResponse({'MESSAGE':'KEY_ERROR'}, status=400)
except IntegrityError:
return JsonResponse({'MESSAGE':'USER_ALREADY_EXISTS'}, status=400)
REGEX = {
'email' : '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',
'password' : '[A-Za-z0-9@#$%^&+=]{8,}',
'name' : '''^([A-Z][a-z]+([ ]?[a-z]?['-]?[A-Z][a-z]+)*)$|^[가-힣]{2,}''',
'phone_number' : '^[0-9]{3}[-]+[0-9]{3,4}[-]+[0-9]{4}$'
}
def validate_email(email):
return re.search(REGEX['email'], email)
def validate_password(password):
return re.search(REGEX['password'], password)
def validate_name(name):
return re.search(REGEX['name'], name)
def validate_phone_number(phone_number):
return re.search(REGEX['phone_number'], phone_number)
REGEX는 상수이기 때문에 대문자로 표현
validation
진행bcrypt
를 사용한 password 암호화IntegrityError
예외 처리python
의 내장 모듈인 json
을 사용하여 Body로 전달받은 json
을 python
의 dict
로 변환validator
에서 정보들 유효성 검증bcrypt
로 암호화하여 변수에 저장Charfield
를 사용했기 때문에 decode진행OperationalError
가 나왔는데 MySQL
에서도 이미 인코딩 처리를 했는데 오류가 계속 나와서 찾다보니 Django settings.py
에 옵션 설정을 따로 해줘야 문제없이 사용 가능하다고 하여 변경함DATABASES = {
'default' : {
····
'OPTIONS': {
'charset': 'utf8mb4',
}
}
}
이 부분을 넣어주지 않으면 결국 DB내에 이모지를 사용할 수 없어서 글쓰기 할 때도 내용에 이모지를 집어넣을 수 없어서 정말 필수로 필요한 사항인듯 하다
password
넣을 시 decoding
해주지 않으면 Sign In 진행 시 오류가 나와서 확인 해 보니 기본 모델링 할 때 Binaryfield
가 아닌 Charfield
로 설정해놔서 byte
가 그냥 string
으로 변경되어 버리는듯,,,decode
하고 넣었더니 정상 작동함모든 통신은
POSTMAN
을 사용하여 진행했습니다
DB에 정상적으로 정보들과
password
가 암호화 되어서 들어간 것을 확인할 수 있다
휴대폰 번호를 동일하게 했을 때 가입이 되지 않음
validation
실패했을 경우 가입 안됨
잘못된
Key
를 전달 했을 경우
처음이라서 그런지 시간도 은근히 오래 걸리고 예외 처리 생각할 부분들이 많아서 로직을 잘 짜놓지 않으면 바로 뚫려버린다... 가장 기본적이고 중요한 부분이기 때문에 평소에 회원가입할 때도 어떤 것이 있고 어떤 것이 들어가야 할 것 같은지 생각을 많이 해봐야겠다!
이것도 완벽한 로직은 아니겠지만 생각했던 문제들은 거의 다 잡혀서 다행인 듯😣
회원가입 부분은 완성한지 오래되었는데도 이제야 쓰게 되어서 기억이 가물가물했다..
완성하게 되면 최대한 빨리 기록해서 복습하는 습관을 들여야겠다!
⛔문제 있는 부분은 언제든지 댓글로 FEEDBACK 부탁드립니다!