Models.py 셋팅
Views.py 내용
class UserView(View):
def post(self, request):
try:
data = json.loads(request.body)
username = data['username']
first_name = data['first_name']
last_name = data['last_name']
email = data['email']
password = data['password']
phone_number = data['phone_number']
EMAIL_REGEX = '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
PHONE_NUMBER_REGEX = '\d{3}-\d{3,4}-\d{4}'
PASSWORD_REGEX = '^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,}$'
if bool(username) == False:
return JsonResponse({'message' : 'UsernameNotFound'} , status = 400)
if User.objects.filter(username = username).exists():
return JsonResponse({'message' : 'UsernameDuplicateError'} , status = 400)
elif User.objects.filter(email = email).exists():
return JsonResponse({'message' : 'EmailDuplicateError'} , status = 400)
elif User.objects.filter(phone_number = phone_number).exists():
return JsonResponse({'message' : 'PhoneNumberDuplicateError'} , status = 400)
if not re.match(EMAIL_REGEX, email):
return JsonResponse({'message' : 'EmailRegexError'} , status = 400)
elif not re.match(PHONE_NUMBER_REGEX, phone_number):
return JsonResponse({'message' : 'PhoneNumberRegexError'} , status = 400)
elif not re.match(PASSWORD_REGEX, password):
return JsonResponse({'message' : 'PasswordRegexError'} , status = 400)
User.objects.create(
username = username ,
first_name = first_name ,
last_name = last_name ,
email = email ,
password = password ,
phone_number = phone_number
)
return JsonResponse({'message' : 'SUCCESS'} , status = 201)
except KeyError:
return JsonResponse({'message' : 'KeyError'} , status = 400)
기본셋팅
- data : Json Api를 딕셔너리 형태로 받은데이터
- 각변수들 : 딕셔너리에서 키로 접근하여 각각의 데이터를 변수에 할당
- 상수들 (대문자로형성된 변수) : email,password,phone_number의 정규표현식
- User.objects.create(~~~) : 위에서 모든 검증과정이 끝났을때 DB에 데이터를 넣는 Django QuerySet Api
변수에 먼저 data 할당하기
예전에 처음 django를 접했을때 create 안에 인자값으로 데이터를 직접 넣은적이 있습니다.
잘못된 데이터가 들어가는 문제도 있겠지만 QuerySetApi를 연속적으로 실행시킬때 문제가 발생할 수 있습니다.
ex)
def ding():
Model1.objects.create(name ='ding', age=29)
Model2.objects.create(name ="ding's brother", age = 301, model1_id = 1)
어떤함수내부에 이러한 코드가 있다고 가정을해본다면
ding's brother의 나이가 이상하다? 301살? 만약 age model의 max_length 가 설정되어있다면 오류가 발생합니다.
그러면 굉장히 귀찮은 문제가 발생되는데...
Model1.objects.create는 실행이 완료되어서 데이터가 db에 들어가고
Model2.objects.create는 안들어간다. 그래서 함수를 한번더 실행시키면
Model1 부터 순차적으로 실행되기때문에 결과적으로 name='ding' , age= 29 라는 데이터가 두번 들어가는문제가 일어납니다.
이런구조를 가진다면 오류가 일어났을때 데이터가 어디까지 들어갔나 다 확인해야됩니다...
(실제로 딕셔너리형태로 함수 만들어서 넣으려다가 머리터질뻔했습니다.)
그래서 저는 create문 안의 인자들은 위에서 변수로 할당해서 넣는편입니다.
1. username 유효성검사 코드
if bool(username) == False:
return JsonResponse({'message' : 'UsernameNotFound'} , status = 400)
CharField의 default속성중에 blank=True가 있습니다.
공백의 문자열 즉 ''를 받아들이는건데 이경우에는 username이 인스타 id이기때문에 사실상 말이 안된다고 생각했습니다.
그래서 공백의 username(인스타그램 id)를 판별후 400에러를 반환하는 구조입니다.
2. 중복검사
if User.objects.filter(username = username).exists():
return JsonResponse({'message' : 'UsernameDuplicateError'} , status = 400)
elif User.objects.filter(email = email).exists():
return JsonResponse({'message' : 'EmailDuplicateError'} , status = 400)
elif User.objects.filter(phone_number = phone_number).exists():
return JsonResponse({'message' : 'PhoneNumberDuplicateError'} , status = 400)
db에 접근해서 해당 데이터가 이미 있나 하는것을 검사하는과정입니다.
User.objects.filter(조건).exists()
위의 쿼리셋은 조건에 해당하는 데이터가 있으면 True를 반환하는 식입니다.(없으면 False)
if조건문은 조건이 True일경우에 실행됩니다.
exists()의 반환값이 True일경우 이미 데이터가 있다는것이기에 바로 return 으로 돌아 에러를 반환합니다.
위의 3가지 if,elif 조건문중에 한번이라도 True값이 반환된다면 에러가 발생합니다.
3.정규표현식을통한 유효성검사
if not re.match(EMAIL_REGEX, email):
return JsonResponse({'message' : 'EmailRegexError'} , status = 400)
elif not re.match(PHONE_NUMBER_REGEX, phone_number):
return JsonResponse({'message' : 'PhoneNumberRegexError'} , status = 400)
elif not re.match(PASSWORD_REGEX, password):
return JsonResponse({'message' : 'PasswordRegexError'} , status = 400)
re모듈의 match함수를 사용해서 정규표현식으로 각데이터들의 유효성을 검사합니다.
match함수 역시 True False로 나오기때문에 만일 정규표현식의 조건을 통과한다면 return 문을 진행하지않습니다.
왜냐면 조건이 not re.match이기때문입니다 match함수의 반환값이 True이면 False로 변하기때문에 진행되지 않습니다.
만약 match함수의 조건이 False이면 not True 즉 False이기에 에러를 반환합니다.
4.KeyError 예외처리
except KeyError:
return JsonResponse({'message' : 'KeyError'} , status = 400)
가장 아래 KeyError에 대한 예외처리가있습니다. 이 예외는 어디서 발생할까요?
username = data['username']
first_name = data['first_name']
last_name = data['last_name']
email = data['email']
password = data['password']
phone_number = data['phone_number']
바로 최상단의 변수선언시에 발생합니다.
data 딕셔너리에 key로 접근하기에 여기서 접근이 안된다면 바로 KeyError가 발생하는 것 입니다.
5.create문으로 데이터 입력 후 SUCCESS 반환
User.objects.create(
username = username ,
first_name = first_name ,
last_name = last_name ,
email = email ,
password = password ,
phone_number = phone_number
)
return JsonResponse({'message' : 'SUCCESS'} , status = 201)
사실 위의 일련의 과정들이 모두 정상작동을한다면 create문에 문제는 없습니다.
그것을 위한 과정이기때문입니다.
만들고 느낀소감...
사실 이 View를 작성할때 굉장히 많은 과정과 많은 방식을 거쳤습니다.
하지만 가장 Basic한 방법이지만 중간중간 return문이 너무 많이나와서 이를 고치고자 또 다른 방법으로 작성하게 되었습니다.
이후에 또 포스팅 하겠습니다.
'Python > Django' 카테고리의 다른 글
[Django] Westagram 회원가입 기능 작성해보기 ver.3 (0) | 2022.06.13 |
---|---|
[Django] Westagram 회원가입 기능 작성해보기 ver.2 (0) | 2022.06.13 |
[Django] QuerySet 기본적인 속성과 Field lookups (0) | 2022.06.09 |
[Django]ManyToMany Field 는 왜 사용할까 (0) | 2022.06.08 |
[django.models] ManyToMany 속성 (0) | 2022.06.08 |