Django Assignment 1 | Westagram 2)

김기현·2022년 2월 19일
0
post-thumbnail

[Mission 3] 회원가입 기능 구현

미션

  • 회원가입 View 기능
    1. 사용자 정보는 이름, 이메일, 비밀번호, 연락처(휴대폰), 그 외 개인정보를 포함합니다.
    2. Email validation : 이메일이나 패스워드가 전달되지 않을 경우, {"message": "KEY_ERROR"}, status code 400 을 반환합니다.
    3. Password Validation : 이메일에는 @와 .이 필수로 포함되어야 합니다. 해당 조건이 만족되지 않은 경우 적절한 에러를 반환합니다. (정규표현식을 활용)
    4. 비밀번호는 8자리 이상, 문자, 숫자, 특수문자의 복합이어야 합니다. 해당 조건이 만족되지 않은 경우, 적절한 에러를 반환해주세요. (정규표현식을 활용)
    5. 회원가입시 서로 다른 사람이 같은 이메일을 사용하지 않으므로, 기존에 존재하는 자료와 중복될 시 적절한 에러를 반환해주세요.
    6. 회원가입이 성공하면 {"message": "SUCCESS"}, status code 201을 반환합니다.

  • URLconf 정의
    1. 클라이언트의 요청을 받아서 회원가입 뷰를 호출할 수 있도록 urls.py 를 작성해야 하며 미에 맞는 url을 생성합니다. (+ 명확성을 보여주는 단어를 선택)

  • 회원가입 확인
    1. httpie를 이용해서 서로 다른 10개의 계정을 회원가입 해주세요.

수정 사항들 내용

  • models.py phone_number이 db에 들어갈 수 있도록 길이 연장
  • migrate 오류 확인 및 migrate
  • httpie 설치
  • created_at, updated_at을 위한 config timezone 수정 완료
  • 이메일이나 패스워드가 전달되지 않을 경우 Key_Error 반환
  • 이메일에 @와 .이 포함되지 않을 경우 Invalid Email 반환
  • 비밀번호가 8자리 이상, 문자, 숫자, 특수문자의 복합이 아닐경우 Invalid Password 반환
  • 같은 이메일 등록 시 Email Already Exist 반환
  • 회원가입 성공 시 User Created! 반환하고 DB에 회원정보 저장

코드 초안

1. 수정하기 전 config/urls

from django.urls import path, include

urlpatterns = [
    path("westargram/", include('users.urls')),
]

2. 수정하기 전 users/urls

from django.urls import path, include
from users.views import SignUpView

urlpatterns = [
    path("signup", SignUpView.as_view()),

]

3. 수정하기 전 users/models

	...
    phone_number = models.CharField(max_length=20)

4. 수정하기 전 users/views

import json
import re

from django.http  import JsonResponse
from django.views import View

from users.models import User


class SignUpView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            
            # Email, Password 정규식
            EMAIL_VALIDATION    = r'^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
            PASSWORD_VALIDATION = r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
            
            # 필드값 받기(여러번 활용하기 위함)
            email               = data['email']
            password            = data['password']
            phone_number        = data['phone_number'],

			# 사용자로부터 받은 email이 EMAIL_VALIDATION에 일치하지 않으면 JsonResponse 반환
            if not re.match(EMAIL_VALIDATION, email):
                return JsonResponse({'Message' : 'Invalid Email'},       status = 400)
            
            # password가 PASSWORD_VALIDATION에 일치하지 않으면 JsonResponse를 반환
            if not re.match(PASSWORD_VALIDATION, password):
                return JsonResponse({'Message' : 'Invalid Password'},    status = 400)

			# email이 이미 사용하고 있다면(filter 활용) JsonResponse를 반환
            if User.objects.filter(email = email).exists():
                return JsonResponse({'Message' : 'Email Already Exist '}, status = 400)

			# 위의 validate를 통과한 후 다음의 항목을 포함한 user를 생성합니다.
            User.objects.create(
                first_name   = data["first_name"],
                last_name    = data["last_name"],
                email        = email,
                password     = password,
                phone_number = phone_number,
                created_at   = data["created_at"],
                updated_at   = data["updated_at"],
                
            )
            # user를 생성한 후 JsonResponse를 보냅니다.
            return JsonResponse({"MESSAGE": "User Created!"}, status=201)
		# 필요한 정보 중 빠져있다면 KeyError를 반환합니다.
        except KeyError:
            return JsonResponse({"MESSAGE": "KEY_ERROR"}, status=400)

피드백

수정하기 전 config/urls

  • url 경로 Path에 굳이 westagram을 명시할 필요 X(RESTful API에 입각한 uri는 뒤에 리소스 내용을 담아 주어야 함)

수정하기 전 users/models

  • 모델에 대한 수정은 feature 모델 브랜치를 새로 파서 기능별로 푸시를 진행

수정하기 전 users/views

  • 해당 validation 내용을 다른 파일로 모듈화하여 진행
  • 상태코드 시작 시 굳이 과도하게 스페이싱을 할 필요 X
  • models.py 의 auto now add, auto now의 기능 고민필요

코드 개선안

수정 후 config/urls

from django.urls import path, include

urlpatterns = [
    path("users/", include('users.urls')),
]

validators 제작

import re

# 이메일 validate
def validate_email(email):
	# 이메일의 정규식
    email_regex = r'^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
    # 주어진 email을 email_regex에 match한다.
    return re.match(email_regex, email)

# 비밀번호 validate
def validate_password(password):
	# 패스워드의 정규식
    password_regex = r'^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
    # 주어진 password를 password_regex에 match한다.
    return re.match(password_regex, password)

수정 후 users/views

import re
import json

from django.http  import JsonResponse
from django.views import View

from users.models import User
# validator.py에서 function 가져오기
from users.validators import validate_email, validate_password

class SignUpView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)

            email        = data['email']
            password     = data['password']
            phone_number = data['phone_number']

            # 'if not re.match(PASSWORD_VALIDATION, password):'은 중복된 기능을 사용하며 에러 유발
            if not validate_email(email):
                return JsonResponse({'Message' : 'Invalid Email'}, status = 400)
            
            if not validate_password(password):
                return JsonResponse({'Message' : 'Invalid Password'}, status = 400)
            
            if User.objects.filter(email = email).exists():
                return JsonResponse({'Message' : 'Email Already Exist '}, status = 400)
				
            # 유저 생성 및 반환
            User.objects.create(
                first_name   = data["first_name"],
                last_name    = data["last_name"],
                email        = email,
                password     = password,
                phone_number = phone_number,
                
            )
            return JsonResponse({"MESSAGE": "User Created!"}, status=201)
		
        # 키에러 발생 시 반환
        except KeyError:
            return JsonResponse({"MESSAGE": "KEY_ERROR"}, status=400)
profile
피자, 코드, 커피를 사랑하는 피코커

0개의 댓글