[DRF] 공식 문서 - views의 정리 1 - FBV(api_view)
1. FBV
- @api_view 데코레이터는 Django REST Framework (DRF)에서 제공하는 함수 기반 뷰를 작성할 때 사용되는 데코레이터입니다. 이 데코레이터를 사용하여 API 뷰 함수를 간편하게 작성할 수 있습니다.
- @api_view 데코레이터를 사용하려면 rest_framework.decorators 모듈에서 import해야 합니다.
from rest_framework.decorators import api_view
1) 데코레이터 목적:
- @api_view는 일반적인 Python 함수를 HTTP 요청을 처리할 수 있는 뷰로 변환하기 위해 DRF에서 제공하는 데코레이터입니다.
- 요청 구문 분석 및 응답 형식 지정과 같은 일반적인 작업을 처리하는 데코레이터를 제공하여 API 뷰 생성 프로세스를 단순화하는 데 도움이 됩니다.
2) 지원되는 HTTP 방법:
- @api_view는 뷰가 처리할 수 있는 HTTP 메서드 목록을 가져옵니다. 예를 들어 @api_view(['GET', 'POST'])는 데코레이팅된 함수가 GET 및 POST 요청을 모두 처리할 수 있음을 의미합니다.
- 설정 가능한 HTTP 메서드 목록은 GET, POST, PUT, PATCH 및 DELETE 입니다.
- 데코레이터는 뷰가 지정된 HTTP 메서드에만 응답하고 다른 메서드에서는 "허용되지 않는 메서드" 응답이 발생하도록 보장합니다.
3) 요청 및 응답 개체:
- @api_view로 장식된 함수 내에서 들어오는 HTTP 요청을 나타내는 request 개체에 액세스할 수 있습니다.
'요청' 개체를 사용하여 쿼리 매개변수, 요청 본문, 헤더 등과 같은 클라이언트의 데이터에 액세스합니다.
4) 응답 처리:
- 함수는 DRF Response 객체를 반환해야 합니다. 이 개체는 클라이언트로 다시 전송되는 HTTP 응답을 구성하는 데 사용됩니다.
- Response 개체는 콘텐츠 협상 및 직렬화를 자동으로 처리하여 응답 형식 지정 프로세스를 단순화합니다.
5) 상태 코드:
- DRF의 status 모듈은 응답에 대한 HTTP 상태 코드를 설정하기 위해 일반적으로 @api_view와 함께 사용됩니다. 예를 들어 status.HTTP_200_OK는 성공적인 응답을 나타냅니다.
6) 인증과 권한 검사:
- @api_view 데코레이터는 인증과 권한 검사를 자동으로 수행하지 않습니다. 따라서 필요에 따라 인증과 권한 검사를 수행하는 추가 로직을 뷰 함수 내에서 구현해야 합니다.
6) 예시 코드 :
- views.py 예시
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import User
from .serializers import UserSerializer
@api_view(['GET', 'POST'])
def user_list(request):
"""
List all users or create a new user.
"""
if request.method == 'GET':
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
def user_detail(request, pk):
"""
Retrieve, update, or delete a user instance.
"""
try:
user = User.objects.get(pk=pk)
except User.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = UserSerializer(user)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = UserSerializer(user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'PATCH':
serializer = UserSerializer(user, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
user.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
- urls.py 예시
from django.urls import path
from .views import user_list, user_detail
urlpatterns = [
path('users/', user_list, name='user-list'),
path('users/<int:pk>/', user_detail, name='user-detail'),
]
8) FBV에 사용 추천하는 데코레이션들
1. 인증 및 권한:
- @authentication_classes: 뷰에 사용할 인증 클래스를 지정합니다.
- @permission_classes: 뷰에 대한 액세스를 제어하는 권한 클래스를 지정합니다.
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
@authentication_classes([SessionAuthentication])
@permission_classes([IsAuthenticated])
def authenticated_view(request):
# Your view logic here
- 커스텀 인증, 권한 설정을 하고 싶다면 다음 코드를 참고한다.
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.authentication import BaseAuthentication
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
# Custom Authentication Class
class CustomAuthentication(BaseAuthentication):
def authenticate(self, request):
# Your custom authentication logic goes here
# For example, you might check a custom header in the request
custom_token = request.headers.get('X-Custom-Token')
if not custom_token:
return None
# Perform your custom authentication logic here
# For simplicity, let's assume the custom token is a user token
user = authenticate_user_with_custom_token(custom_token)
if user is None:
return None
return (user, None)
# Custom Permission Class
class CustomPermission(BasePermission):
def has_permission(self, request, view):
# Your custom permission logic goes here
# For example, you might check if the user has a specific role
return request.user and request.user.has_perm('custom_permission')
# Apply the custom authentication and permission classes to your view
@authentication_classes([CustomAuthentication])
@permission_classes([CustomPermission])
def authenticated_view(request):
# Your view logic here
return Response({"message": "Authenticated view accessed successfully"}, status=status.HTTP_200_OK)
2. 스로틀 및 속도 제한:
- @throttle_classes: 뷰에 적용할 스로틀 클래스를 지정하여 요청 속도를 제한합니다.
from rest_framework.decorators import throttle_classes
from rest_framework.throttling import UserRateThrottle
@throttle_classes([UserRateThrottle])
def rate_limited_view(request):
# Your view logic here
3. 캐시 제어:
- @cache_page: 지정된 기간 동안 보기 응답을 캐시하여 캐시된 응답을 제공하여 성능을 향상시킵니다.
from django.views.decorators.cache import cache_page
@cache_page(60 * 15) # Cache for 15 minutes
def cached_view(request):
# Your view logic here
4. 조건부 처리:
- @require_http_methods: 특정 HTTP 메소드에만 응답하도록 뷰를 제한합니다.
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET", "POST"])
def specific_methods_view(request):
# Your view logic here
5. 오류 처리:
- @renderer_classes: 뷰의 렌더러 클래스를 지정하여 응답 형식을 제어합니다.
from rest_framework.decorators import renderer_classes
from rest_framework.renderers import JSONRenderer
@renderer_classes([JSONRenderer])
def json_response_view(request):
# Your view logic here
5. 속도 제한:
- 설치
pip install django-ratelimit
- settings.py
# Set rate limit for anonymous users
RATELIMIT_ANONYMOUS = '10/minute'
# Set rate limit for authenticated users
RATELIMIT_USER = '10/minute'
- views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django_ratelimit.decorators import ratelimit
@api_view(['GET', 'POST'])
@ratelimit(key='user', rate='10/minute', block=True)
def rate_limited_api_view(request):
"""
A rate-limited API view that allows GET and POST requests.
"""
if request.method == 'GET':
# Your GET logic here
return Response({'message': 'GET request processed'})
elif request.method == 'POST':
# Your POST logic here
data = request.data
return Response({'message': 'POST request processed', 'data': data})
- @ratelimit(key='user', rate='10/min', block=True)는 속도 제한을 적용하는 데 사용됩니다. 사용자는 분당 10개의 요청으로 제한되며, 사용자가 이 한도를 초과하면 추가 요청이 차단됩니다(block=True).
- 사용자를 식별하려는 방법에 따라 key 매개변수를 조정하세요. 이 경우 사용자의 IP 주소(key='user')를 사용하지만 요구 사항에 따라 맞춤 설정할 수 있습니다.
- 공식 사이트 문서 : https://www.django-rest-framework.org/api-guide/views/#function-based-views
- reference :
https://blog.dnd.ac/django-restframe-work-views/