@@ -0,0 +1,87 @@
+import re, json, bcrypt
+
+from django.views                 import View
+from django.http                  import JsonResponse, request
+from django.db.models.query_utils import Q
+from json.decoder                 import JSONDecodeError
+
+from user.utils  import LoginCheck
+from user.models import User
+
+class SignUpView(View):
+    def post(self, request):
+        try:
+            data = json.loads(request.body)
+
+            email         = data['email']
+            password      = data['password']
+            phone         = data.get('phone', None)
+            full_name     = data.get('full_name', None)
+            user_name     = data.get('user_name', None)
+            date_of_birth = data.get('date_of_birth', None)
+
+            if phone:
+                phone = phone.replace('-','')
+
+            REGEX_EMAIL    = '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
+            REGEX_PASSWORD = '\S{8,20}'
+
+            if not re.match(REGEX_EMAIL,email):
+                return JsonResponse({'message':'EMAIL VALIDATION ERROR'}, status=400)
+            if not re.match(REGEX_PASSWORD,password):
+                return JsonResponse({'message':'PASSWORD VALIDATION ERROR'}, status=400)
+
+            if not User.objects.filter(email=email):
+                if phone and User.objects.filter(phone=phone):
+                    return JsonResponse({'message':'PHONE ALREADY EXISTS'}, status=400)
+                elif user_name and User.objects.filter(user_name=user_name):
+                    return JsonResponse({'message':'USER_NAME ALREADY EXISTS'}, status=400)
+            else:
+                return JsonResponse({'message':'EMAIL ALREADY EXISTS'}, status=400)
+
+            hashed_password = bcrypt.hashpw(password.encode('UTF-8'), bcrypt.gensalt()).decode()
+
+            User.objects.create(
+                email         = email,
+                phone         = phone,
+                full_name     = full_name,
+                user_name     = user_name,
+                password      = hashed_password,
+                date_of_birth = date_of_birth,
+            )
+
+            return JsonResponse({'message':'SUCCESS'}, status=200)     
+
+        except KeyError:
+            return JsonResponse({'message':'KEY ERROR'}, status=400)
+        except JSONDecodeError:
+            return JsonResponse({'message':'JSON DECODE ERROR'}, status=400)
+        except Exception as e:
+            print(e)
+
+
+class SignInView(View):
+    def post(self, request):
+        try:
+            data = json.loads(request.body)
+
+            user_id  = data['user_id']
+            password = data['password']
+
+            user= User.objects.get(Q(user_name=user_id)|Q(email=user_id)|Q(phone=user_id))
+
+            if user:
+                stored_password  = User.objects.get(Q(user_name=user_id)|Q(email=user_id)|Q(phone=user_id)).password
+                if not bcrypt.checkpw(password.encode('UTF-8'), stored_password.encode('UTF-8')):
+                    return JsonResponse({"message":"INVALID_PASSWORD"}, status=401)                
+            else:
+                return JsonResponse({"message":"INVALID_USER"}, status=401)   
+            
+            return JsonResponse({"message":"SUCCESS", "Authorization":LoginCheck(user.id)}, status=200)
+
+        except KeyError:
+            return JsonResponse({"message":"KEY_ERROR"}, status=400)
+        except JSONDecodeError:
+            return JsonResponse({'message':'JSON DECODE ERROR'}, status=400)
+        except Exception as e:
+            print(e)
\ No newline at end of file

리뷰: 이미 존재하는 정보인지 확인하는 로직을 작성해주셨는데 작성해주신 로직을 흐름대로 글로 정리해보겠습니다.
1. 입력받은 `email` 값으로 유저 테이블에 filter 쿼리를 날려 반환받은 QuerySet 리스트에 객체가 존재하지 않는다면 `phone_number` 과 `user_name` 으로 filter 쿼리를 날려 추가 확인을 한다.
2. 존재한다면 `400` 을 리턴해준다. 

하지만 현재 `SignUp` View 에서는 `email` 을 필수값으로 받아야하기 때문에 사실상 `email` 존재 유무만 확인해도 등록된 유저인지 아닌지는 알 수가 있습니다. `phone_number` 와 `user_name` 은 부가정보들이니까요!

그런데 `email` 로 존재유무는 확인하더라도 `phone_number` 와 `user_name` 의 중복 가능 여부에 따라 추가 로직은 달라질 수 있습니다. 제가 모델쪽에 남겨드린 리뷰를 확인해보신 후 생각하신 구조에 따라 수정해주신 다음 다시한번 이쪽 부분을 확인해보세요!