DRF 视图装饰器 #

一、装饰器概述 #

1.1 常用装饰器 #

装饰器 说明
@api_view 声明支持的HTTP方法
@authentication_classes 设置认证类
@permission_classes 设置权限类
@throttle_classes 设置限流类
@schema 设置API文档

1.2 装饰器应用场景 #

  • 函数视图
  • 类视图方法
  • ViewSet action

二、@api_view #

2.1 基本用法 #

python
from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET'])
def hello(request):
    return Response({'message': 'Hello!'})

@api_view(['GET', 'POST'])
def article_list(request):
    if request.method == 'GET':
        return Response({'method': 'GET'})
    return Response({'method': 'POST'})

2.2 参数说明 #

python
@api_view(
    ['GET', 'POST'],  # 支持的HTTP方法
    exclude_from_schema=False  # 是否从API文档中排除
)
def my_view(request):
    return Response({'ok': True})

三、@authentication_classes #

3.1 函数视图 #

python
from rest_framework.decorators import authentication_classes
from rest_framework.authentication import TokenAuthentication

@api_view(['GET'])
@authentication_classes([TokenAuthentication])
def protected_view(request):
    return Response({'user': request.user.username})

3.2 类视图方法 #

python
from rest_framework.decorators import authentication_classes
from rest_framework.authentication import TokenAuthentication

class ArticleView(APIView):
    @authentication_classes([TokenAuthentication])
    def get(self, request):
        return Response({'user': request.user.username})

四、@permission_classes #

4.1 基本用法 #

python
from rest_framework.decorators import permission_classes
from rest_framework.permissions import IsAuthenticated

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def profile(request):
    return Response({'username': request.user.username})

4.2 组合权限 #

python
from rest_framework.permissions import IsAuthenticated, IsAdminUser

@api_view(['DELETE'])
@permission_classes([IsAuthenticated, IsAdminUser])
def delete_all(request):
    Article.objects.all().delete()
    return Response({'message': '已删除所有文章'})

五、@throttle_classes #

5.1 基本用法 #

python
from rest_framework.decorators import throttle_classes
from rest_framework.throttling import AnonRateThrottle

class OncePerDayThrottle(AnonRateThrottle):
    rate = '1/day'

@api_view(['GET'])
@throttle_classes([OncePerDayThrottle])
def limited_view(request):
    return Response({'message': '每天只能访问一次'})

5.2 组合限流 #

python
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle

@api_view(['GET'])
@throttle_classes([AnonRateThrottle, UserRateThrottle])
def throttled_view(request):
    return Response({'message': 'ok'})

六、@action装饰器 #

6.1 基本用法 #

python
from rest_framework.decorators import action

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    
    @action(detail=True, methods=['post'])
    def publish(self, request, pk=None):
        article = self.get_object()
        article.is_published = True
        article.save()
        return Response({'status': 'published'})

6.2 完整参数 #

python
@action(
    detail=True,                    # True=单个对象,False=列表
    methods=['get', 'post'],        # 支持的HTTP方法
    url_path='custom-path',         # 自定义URL路径
    url_name='custom-name',         # 自定义URL名称
    permission_classes=[IsAuthenticated],  # 权限类
    authentication_classes=[TokenAuthentication],  # 认证类
    throttle_classes=[UserRateThrottle],  # 限流类
    schema=None                     # API文档schema
)
def custom_action(self, request, pk=None):
    return Response({'action': 'custom'})

七、装饰器组合 #

7.1 完整示例 #

python
from rest_framework.decorators import (
    api_view, authentication_classes, 
    permission_classes, throttle_classes
)
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.throttling import UserRateThrottle

@api_view(['GET', 'POST'])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
@throttle_classes([UserRateThrottle])
def article_list(request):
    if request.method == 'GET':
        articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)
    
    serializer = ArticleSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save(author=request.user)
    return Response(serializer.data, status=201)

八、总结 #

本章学习了DRF视图装饰器:

  • @api_view:声明HTTP方法
  • @authentication_classes:设置认证
  • @permission_classes:设置权限
  • @throttle_classes:设置限流
  • @action:ViewSet自定义动作

装饰器提供了灵活的视图配置方式!

最后更新:2026-03-28