Today I Learned | 7월 29일

10143 단어 TILTIL

오늘 뭐했지 🍑

1 Code Kata day9
2 Westagram Wrap-up


1. 🍑 Code Kata day9 🍑

👉 링크

2. 🍑 Westagram Wrap-up 🍑

어제 프론트엔드와 위스타그램 코드를 붙여보는 시간이 있다. 회원가입과 로그인 API 모두 확인해보는데 로그인 API에서 500오류가 계속 떠서 이게 대체 뭐가 문제야 ? 하고 40분 넘게 고민했다. . 오늘 세션시간에 설명을 듣고 해결했다.

문제의 코드

users/views.py

try :
    data     = json.loads(request.body)
    email    = data['email']
    password = data['password']
    user = User.objects.get(email=email)
    
    if not User.objects.filter(email=email).exists():
        return JsonResponse({'message':'INVALID_EMAIL'}, status=401)

사용자가 입력한 email이 DB에 있는지 확인하고 없으면 '유효하지 않은 이메일'이라고 에러메시지를 띄우는 로직을 확인하는 작업이었다. DB에 없는 이메일을 서버로 보내면
User.DoesNotExist:User matching query does not exist. 라는 에러가 발생했다.

깃헙에서 다른 분들이 짠 코드를 확인해봐도 if문에 exists메소드를 사용한 것 까지 똑같았는데 대체 왜 에러가 나는걸까 고민하다가 'user'라는 변수의 위치를 바꾸면 에러없이 정상적으로 작동한다는 사실을 알았다. 이유는 내 선에서 알 수 없었다 . . ^^ 그리고 오늘 세션에서 이에 대한 설명을 들을 수 있었다.

user라는 변수에는 json데이터에 담겨져 온 email과 일치하는 email값을 갖는 객체가 할당된다. 이 변수가 if문을 통한 객체의 유무존재를 필터링하기도 전에 등장해서 있지도 않은 값을 할당하라고 하니까 User.DoesNotExist 에러가 발생한 것이다.
내 딴에선 코딩 컨벤션에 신경쓰며 변수들을 줄맞춰서 한데에 정리해보려하다가 로직의 순서를 파괴하고 말았다. 💩

수정한 코드

try :
    data     = json.loads(request.body)
    email    = data['email']
    password = data['password']
   
    if not User.objects.filter(email=email).exists():
        return JsonResponse({'message':'INVALID_EMAIL'}, status=401)
        
    user = User.objects.get(email=email)   

user 변수의 위치를 if 문 아래로 옮기면 에러없이 정상으로 작동한다.

기타 Tip

  • 백엔드 협업시 model 수정은 한 사람이 맡아서 할 것.
    migration 파일이 동일하지 않을 경우 github에서 공유 시 충돌함
  • print() 함수를 이용해 디버깅 하기

데코레이터 완성 ~ !

users/utils.py

import json, jwt

from django.http import JsonResponse

from my_settings  import SECRET_KEY
from users.models import User

def login_required(f):
    def wrapper(self, request, *ars, *kwargs):
        try:
            access_token = request.headers['Authorization']
            
            if access_token:
                payload = jwt.decode(access_token, SECRET_KEY, algorithms='HS256')
                user = User.objects.get(id = payload['id'])
                request.user = user.id
                
                return f(self, request, *args, **kwargs)
                
        except jwt.exceptions.DecodeError:
            return JsonResponse({'message':'invalid_access_token'}, status=400)
        except keyError:
            return JsonResponse({'message':'sign_up_first'}, status=400)
    return wrapper

이 코드 적는데 며칠이 걸린지 .. ^^ 데코레이터라는 개념이 익숙하지않기도 하고
request 메세지로 오는 데이터를 어떻게 받고, 어떻게 사용해야할 지 생각하는게 거의 무에서 유를 창조해야하는 수준의 난이도라 좀 힘들었다 하하......
try밖으로 쓴 코드가 문제가 되서 에러도 자꾸 생겼고
그래서 결론은 처음부터 잘 쓰자 . . 중간에 오타나거나 실수해서 오류나면 찾기가 어렵다
(algorithms 라고 써야하는데 algorithm 이라고 써서 몇번을 처음부터 끝까지 읽었는지...)

좋은 웹페이지 즐겨찾기