회원가입 시 이미 존재하고 있는 e-mail에 대해 중복 에러를 아래와 같이 작성하였습니다.
if User.objects.filter(email=email).exists():
return JsonResponse({"message":"Duplication_ERROR"}, status=400)
코드의 내용은 User의 객체에서 email에 해당하는 것만 필터링하여 불러와서 존재하는지 판단하여 존재할 시 중복에러를 발생시키는 작업입니다.
이 방법이 효율적인 이유는 다음과 같습니다.
상위 코드는 DB에 어떤 쿼리도 전달하지 않습니다. DB에 아무런 메시지도 전달하지 않기 때문에 장점으로 볼 수 있습니다. 왜냐하면 DB에 쿼리를 전달하게 되면 웹 애플리케이션을 느려지게 하기 때문입니다. DB의 레코드를 진짜로 가져오기 위해서는 for문으로 쿼리셋을 순회해야하는데 이 경우 DB의 레코드를 실제로 가져오고 장고 모델로 변환되므로 속도적으로 조금 불리할 수 있습니다.
또한 exists()의 경우 쿼리셋 캐시를 만들지 않으면서 레코드가 존재하는지 검사합니다.
(쿼리셋에 if문으로 존재여부를 판단하게 되면(True/False) if문 때문에 쿼리셋이 '평가'되고 이에 따라 쿼리셋 캐시에도 전체 레코드가 저장되어 비효율적입니다.)
따라서 DB에서 가져온 레코드가 하나도 없다면 트래픽과 메모리를 절약할 수 있습니다.
(레코드의 데이터가 커질수록 데이터를 한번에 가져오는 것이 매우 비효율적입니다)
import json
import re
from django.http import JsonResponse
from django.views import View
from users.models import User
class UsersView(View):
def post(self, request):
try:
data = json.loads(request.body)
email = data["email"]
password = data["password"]
email_validation = re.compile("^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
password_validation = re.compile("^.*(?=^.{8,}$)(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%*^&+=]).*$")
if email == "" or password == "":
return JsonResponse({"message":"KEY_ERROR"}, status=400)
if not email_validation.match(email):
return JsonResponse({"message":"EMAIL_VALIDATION_ERROR"}, status=400)
if not password_validation.match(password):
return JsonResponse({"message":"PASSWORD_VALIDATION_ERROR"}, status=400)
if User.objects.filter(email=email).exists():
return JsonResponse({"message":"DUPLICATION_ERROR"}, status=400)
User.objects.create(
name = data["name"],
email = data["email"],
password = data["password"],
contact_mobile = data["contact_mobile"],
nickname = data["nickname"],
address = data["address"],
)
return JsonResponse({"message": "SUCCESS"}, status=201)
except KeyError:
return JsonResponse({"message":"KEY_ERROR"}, status=400)
참고자료 http://raccoonyy.github.io/using-django-querysets-effectively-translate/