TIL 30. 회원가입 email 중복 에러(objects.filter().exists())

윤현묵·2021년 8월 23일
4

Django

목록 보기
6/17
post-thumbnail
post-custom-banner

회원가입 시 이미 존재하고 있는 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/

profile
진정성 있는 개발자를 꿈꾼다
post-custom-banner

0개의 댓글