Sign In
TIL 웹개발

TIL 웹개발 - Django쟝고에서 Decorator 데코레이터 사용하기

서경태
Django에서 데코레이터는 웹 애플리케이션의 특정 기능을 쉽게 구현할 수 있도록 도와준다. 주로 인증, 권한 관리, 보안, 캐싱 등의 기능을 위해 사용된다.
@login_required : 로그인된 사용자만 접근 가능
@permisison_required : 특정 권한이 있는 사용자만 접근 가능
@crsf_exempt : CSRF 검사를 비활성화
@require_http_mothods : 지정된 HTTP 메소드만 허용
@require_POST: POST 요청만 허용
@cache_page: 지정된 시간동안 캐싱하여 출력 성능 향상
@transaction.atomic: 하나의 트랜잭션으로 모든 DB작업 처리
위 데코레이터들은 쟝고에서 주로 사용되는 것들인데 이제 하나씩 알아보자.

@login_required

사용자가 로그인하지 않은 상태에서 이 데코레이터가 사용된 뷰에 접근하면 로그인 페이지로 다이렉트를 하는 기능 제공한다.
from django.contrib.auth.decorators import login_required @login_required def my_view(request): # 로그인한 사용자만 이 뷰에 접근 가능 return render(request, 'my_template.html')
이렇게 사용하면 my_view에 접근하기 위해 로그인이 필요하고 로그인하지 않은 경우 로그인 페이지로 이동한다. (물론 로그인 페이지가 있는 경우)
이때 두 가지 방법으로 로그인 페이지를 login_required와 연결할 수 있다.
1.
직접 login_url 설정
@login_reqired 데코레이터 함수를 보면 다음과 같이 작성되어 있다.
def login_required( function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None ): """ Decorator for views that checks that the user is logged in, redirecting to the log-in page if necessary. """ actual_decorator = user_passes_test( lambda u: u.is_authenticated, login_url=login_url, redirect_field_name=redirect_field_name, ) if function: return actual_decorator(function) return actual_decorator
여기서 login_url = None으로 되어있는데 이 부분을 로그인 페이지로 설정하면 데코레이터가 정상적으로 작동한다.
2.
accounts / login.html 설정
쟝고의 기본 설정에 따라 아래 그림처럼 페이지를 구성하면 @login_required를 사용할 수 있다.
로그인 페이지를 accounts 폴더에 위치시키면 쟝고가 알아서 해당 페이지를 리다이렉트해준다.
로그인 후에는 사용하던 페이지의 url을 next 파라미터에 저장해 다시 리다이렉트 해주니 굉장히 편리한 기능이다.

@permisison_required

특정 권한이 있는 사용자만 해당 뷰에 접근할 수 있게 제한한다. 권한이 없는 사용자가 접근할 경우 403 Forbidden 응답을 받는다.
from django.contrib.auth.decorators import permission_required @permission_required('app_label.permission_codename') def my_view(request): # 특정 권한이 있는 사용자만 접근 가능 return render(request, 'my_template.html')

@csrf_exempt

특정 뷰에서 CSRF 검사를 하지 않아도 작동하도록 설정한다. http POST를 사용하면 csrf_token을 포함하지 않아도 된다.
from django.views.decorators.csrf import csrf_exempt @csrf_exempt def my_view(request): if request.method == "POST": # POST 요청 처리 pass return HttpResponse('CSRF 보호가 비활성화된 뷰입니다.')
http POST 요청에는 기본적으로 보안을 위해 CSRF 검사를 활성화하는데 아래와 같은 경우 사용한다.
서드파티 서비스와의 통합
API 엔드포인트
클라이언트에서 직접 호출하는 뷰
서버 간 통신
서버가 CSRF를 관리하는 방식이 다른 경우

@require_http_methods

특정 http 메소드(GET, POST, PUT, DELETE 등)만 허용하도록 제한한다.
from django.views.decorators.http import require_http_methods @require_http_methods(["GET", "POST"]) def my_view(request): # GET 또는 POST 요청만 허용 return render(request, 'my_template.html')
데코레이터를 작성하고 리스트 안에 허용할 요청방식을 적어주면 된다.
@require_POST
@require_GET
처럼 하나만 사용할 경우 위처럼 적어서 사용할 수 있다.

@cache_page

특정 뷰의 출력을 캐싱하여 성능을 향상시킨다. 설정된 시간 동안 동일한 요청에 대해 데이터베이스 조회나 처리 없이 빠르게 동일한 응답을 반환한다.
from django.views.decorators.cache import cache_page @cache_page(60 * 15) # 15분 동안 캐싱 def my_view(request): # 이 뷰의 결과가 15분 동안 캐시됨 return render(request, 'my_template.html')
웹 페이지가 자주 변경되지 않고 동일한 콘텐츠를 여러 번 제공하는 경우(블로그, 포슽, 뉴스 기사 등) @cache_page를 사용해 서버 부하를 감소하고 응답 속도를 향상시킨다.

@transaction.atomic

뷰에서 실행되는 모든 데이터베이스 작업이 하나의 트랜잭션으로 처리되도록 보장한다.
from django.db import transaction @transaction.atomic def my_view(request): # 이 뷰의 모든 데이터베이스 작업이 하나의 트랜잭션으로 처리됨 pass
복잡한 데이터베이스 작업을 하나의 트랜잭션으로 묶어서 중간에 오류가 발생했을 때 모든 작업을 원상복구할 수 있다. (예시: 주문 처리 과정에서 여러 데이터베이스 테이블을 업데이트 해야할 때)
모든 데이터베이스 작업이 성공적으로 완료되거나 실패할 때 모든 변경 사항이 롤백되므로 데이터 무결성을 유지한다. 그리고 단일 트랜잭션 처리로 코드의 복잡성을 줄이고 오류를 방지할 수 있다.
Subscribe to 'kyugntae-ai'
Subscribe to my site to be the first to receive notifications and emails about the latest updates, including new posts.
Join Slashpage and subscribe to 'kyugntae-ai'!
Subscribe
👍