TIL_29 | [Django] 장식하면 code가 이뻐지는 매직! Decorator👍
django
를 배우고,
instagram 클론을 진행하다 보니 여러가지 문제에 봉착했다.
바로, 로.그.인.
로그인을 해야만 할 수 있는 문제들을 어떻게 해결 할 수 있을까?
뭘 장식하는 Decorator?!🤔
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
함수가 될수는 없다는 것!
decorator
함수가 되기 위해선 중첩 함수(nested function)을 리턴하는 함수만 decorator
로 사용된다.
즉, decorator
의 기능을 다르게 설명한다면 chain of function
.
여러개의 함수가 연속적으로 호출이 자동으로 되게 해준다!
(한개가 가능하다면 여러개도 가능!🤩)
question 함수를 deocorator 함수로 구현하기
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)
Today, Learned🧑🏻💻
배운점
decorator
가 돌아가는 작동 방법 및 사용 방법!wrap
의 기능
느낀점
- 확실히 사용하고 나니까 모든 로직에서 로그인 했는지에 대한 검사가 없어지니 편하고 좋았다! (코드의 반복성 제거!!)👍👍
- 생각보다 쉽고 편하게 쓰이는 기능인만큼 안쓸 이유가 있을까...?
오늘의 한마디
decorator
.. 장식이라는 뜻이지만 넌 없으면 안되는 녀석이야!!🤩
Author And Source
이 문제에 관하여(TIL_29 | [Django] 장식하면 code가 이뻐지는 매직! Decorator👍), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@code_sign/TIL29저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)