django
를 배우고,
instagram 클론을 진행하다 보니 여러가지 문제에 봉착했다.
바로, 로.그.인.
로그인을 해야만 할 수 있는 문제들을 어떻게 해결 할 수 있을까?
django
에서 말하는 decorator
란 어떤 function
위에 붙어 작동한다.
(그 모습이 function
을 장식하는 것 같다고 해서 decorator
...😂)
우리가 속해있는 모임에 프로 불편러가 있다고 생각해보자💣💣
이 프로 불편러는 사람들이 물어볼때마다 "알아서 뭐할껀데?"라고 반문한다.
그것을 코드로 짜보면 아래와 같을 것 같다.
(원래 이름을 줄여쓰면 안좋지만 너무 길어져 줄여썼다..)
# 프로불편러의 대답 함수
def SJW(): # Social Justice Warrior = 프로불편러
return "알아서 뭐할껀데?"
# 물어보는 함수
def question():
return "이건 이런건가요~?"
근데, 프로불편러가 불편한 대답을 하기 위해선 반드시 그 전에 질문을 받아야 대답을 한다. 즉, 대답을 하기위한 선행과제가 질문이다!
def question():
def SJW()
이렇게 하면 완벽한 코드가 된 것 같지만,
이 프로불편러가 어떤 질문을 받을때만 대답하는 것이 아니라 질문에 물음표만 포함되어 있어도 불편한 답변을 한다고 생각하면, 그 과정을 다 연결시켜주는 것이 번거로울 수 있고 누락될 수도 있다.
그럴때 필요한 것이 decorator
다!
decorator
는 항상 어떤 함수를 실행하기 전에 장식처럼 달린 함수를 먼저 실행한다. 아래와 같이 사용이 가능하다.
@question
def SJW():
return "알아서 뭐할껀데?"
중요한 점은,
아무 함수나 decorator
함수가 될수는 없다는 것!
decorator
함수가 되기 위해선 중첩 함수(nested function)을 리턴하는 함수만 decorator
로 사용된다.
즉, decorator
의 기능을 다르게 설명한다면 chain of function
.
여러개의 함수가 연속적으로 호출이 자동으로 되게 해준다!
(한개가 가능하다면 여러개도 가능!🤩)
def question(func):
ask = True # 간단화 하기 위해 무조건 True
def wrapper(*args, **kwargs):
if ask:
func()
else:
return
return wrapper
이렇게 구현하면 된다!
# 실행 모습!
@login
def SJW():
...
응...? 이게 무슨 소리야?!?!?!?
대충 이런식으로 작동이 된다.
(이해가 될런지...👽)
나는 인스타그램을 구현하는 와중에 로그인하는 기능을 decorator
함수로 만들어 로그인이 필요한 기능들에 사용을 해줬다.
(게시글 등록, 댓글 등록, 팔로우 등등...)
# utils.py
import jwt
import json
import request
from django.http import JsonResponse
from django.conf import settings
from user.models import Accounts
from my_settings import SECRET, ALGORITHM
def login_decorator(func):
def wrapper(self, request, *args, **kwargs):
try:
access_token = request.header['Authorization']
payload = jwt.decode(access_token, SECRET, algorithms=ALGORITHM)
user = Accounts.objects.get(email=payload)
reqeust.user = user
except jwt.exceptions.DecodeError:
return JsonResponse({'message':'INVALID_TOKEN'}, status=400)
except Accounts.DoesNotExist:
return JsonResponse({'message':'INVALID_ACCOUNT'}, status=400)
return func(self, request, *args, **kwargs)
return wrapper
# posting app의 PostingView
# 게시글 등록
@login_decorator
def post(self, request):
data = json.loads(request.body)
try:
account = Accounts.objects.get(nickname=data['account'])
Posting.objects.create(
account = account,
image_url = data['image_url'],
contents = data['contents']
)
return JsonResponse({'message':'SUCCESS'}, status=200)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
decorator
가 돌아가는 작동 방법 및 사용 방법!wrap
의 기능decorator
.. 장식이라는 뜻이지만 넌 없으면 안되는 녀석이야!!🤩