이번에는 회원가입을 할 수 있는 SignUpView
를 작성할 것이다.
signup 브랜치를 만들고 다음과 같이 view를 작성한다.
- 이메일에는
@
,.
가 포함되어 있을 것- 비밀번호는 8자리 이상, 숫자, 문자, 특수문자가 포함되어 있을 것
- 이메일은 중복될 수 없음
- 전화번호 형식에 맞을 것 (개인 구현사항)
- 이메일이나 패스워드 누락 시 Key Error를 발생시킬 것
import json
import re
from django.http import JsonResponse
from django.view import View
from users.models import model
class SignUpView(View):
def post(self, request):
user_data = json.loads(request.body)
try:
user_email = user_data["email"]
user_password = user_data["password"]
user_phone_number = user_date["phone_number"]
# 정규표현식
REGEX_EMAIL = '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
REGEX_PASSWORD = '^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&.]{8,}$'
REGEX_PHONE_NUMBER = '\d{3}-\d{3,4}-\d{4}'
# Email Validation
if not re.match(REGEX_EMAIL, user_email):
return JsonRespones({"message": "INVALID_EMAIL"}, status=400)
# Password Validation
if not re.match(REGEX_PASSWORD, user_password):
return JsonRespones({"message":"INVALID_PASSWORD"}, status=400)
# Phone number Validation
if not re.match(REGEX_PHONE_NUMBER, user_phone_number):
return JsonRespones({"message":"INVALID_PHONE_NUMBER"}, status=400)
# Email Integrity
if User.objects.filter(email=user_email).exists():
return JsonResponse({"message":"EMAIL_ALREADY_EXISTS"}, status=400)
user = User(
name = user_data["name"],
email = user_email,
password = user_password,
phone_number = user_phone_number
)
user.save()
return JsonResponse({"message":"SUCCESS"}, status=201)
except KeyError:
return JsonResponse({"message":"KEY_ERROR"}, status=400)
이렇게 뷰를 작성해주었다면 url맵핑을 해준다.
from django.urls import path
from users.views import SignUpView
urlpatterns = [
path('/signup', SignUpView.as_view()),
]
자주 쓰는 데이터인 경우 변수에 할당해서 사용
-> user_email
같은 데이터를 변수에 할당하지 않고 user_data['email']
같은 형식으로 사용했었는데 이 데이터는 유효성 및 중복 검사에 계속 사용되므로 변수에 할당하는 게 좋다고 한다.
IntegrityError
-> 이메일, 패스워드 누락을 잡는 부분에서 따로 if
문으로 검사하지 않고 바로 except IntegrityError:
로 작성하였는데 이렇게 작성할 시 데이터베이스 상에서 id가 하나씩 밀리는 것이 확인되었다. 이 말은 즉슨 먼저 데이터를 생성하고, 누락된 부분이 있을 시 지우는 것이다. 이렇게 불필요한 동작을 하는 것보다if
, filter().exists()
로 에러를 잡아주는 게 좋다고 한다.
객체 생성
-> 처음에 user 객체를 유효성 검사 전에 미리 생성하게 끔 작성을 했었다. 이렇게 하면 검사가 통과되지 않아도 객체를 미리 생성하게끔 되기 때문에 검사를 다 끝낸 후에 객체를 생성하도록 코드의 순서를 바꾸어 주었다.
url 네이밍
-> 공식 문서에서 url은 _
보다-
를 권장한다고 한다. 따라서 /sign_up
보다는 /sign-up
으로 바꾸는 게 낫다고 한다. 하지만 이 경우에는 /signup
으로 작성해도 된다고 하여 이렇게 작성했다.
re.search() -> re.match()
-> 정규 표현식 문자열 검색 부분에서 처음에는 search()함수를 썼다가 search 보다 match를 사용해야 한다는 피드백을 받아 두 함수의 차이를 구글링해보았다.
💡 search()와 match()의 차이
-search(): 문자열 어느 곳이든 일치하는 문자열이 있을 시 match객체를 반환해준다.
-match(): 문자열 처음부터 일치하는 문자열을 찾는다.
내가 구현하는 Email Validation은 @
나 .
가 문자열 아무 곳에서나 포함되기만하면 되는게 아니라 문자열@문자열.문자열
형태를 이루어야하는 것이기 때문에 이 경우 match()함수를 쓰는 것이 맞다.