You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST Framework中自定义并使用类似get/post的方法?

在Django REST Framework中创建并使用自定义视图方法

核心方式:用@action装饰器(DRF官方推荐)

DRF提供的@action装饰器是添加自定义视图方法最规范的方式,能自动处理路由生成、请求方法绑定等逻辑,和内置的get/post方法用法一致。

步骤1:定义带自定义方法的ViewSet

导入必要模块后,在ViewSet类里用@action装饰自定义方法,指定允许的请求方法、是否需要模型主键(detail参数):

from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer
from rest_framework.permissions import IsAdminUser

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    # 自定义方法:获取热门书籍(不需要主键,detail=False)
    @action(methods=['get'], detail=False)
    def hot_books(self, request):
        hot_books = Book.objects.filter(is_hot=True)
        serializer = self.get_serializer(hot_books, many=True)
        return Response(serializer.data)

    # 自定义方法:标记书籍为已售罄(需要主键,detail=True)
    @action(methods=['post'], detail=True, permission_classes=[IsAdminUser])
    def mark_sold_out(self, request, pk=None):
        book = self.get_object()  # 自动根据pk获取模型实例
        book.is_sold_out = True
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)
  • methods:指定该方法允许的请求类型,比如['get', 'post']
  • detail:设为True表示URL需要传入模型主键,设为False表示不需要
  • 可添加permission_classes、authentication_classes等参数,和内置视图权限控制逻辑一致

步骤2:配置路由自动生成

用DRF的DefaultRouter注册ViewSet后,会自动为自定义方法生成路由:

from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet)
urlpatterns = router.urls

生成的路由对应关系:

  • GET /books/hot_books/ → 调用hot_books方法
  • POST /books/{pk}/mark_sold_out/ → 调用mark_sold_out方法

手动配置路由(适用于APIView场景)

如果不用ViewSet,而是用基础的APIView,可以手动绑定自定义方法到路由:

步骤1:在APIView里定义自定义方法

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

class BookAPIView(APIView):
    def get(self, request):
        # 内置GET方法逻辑:获取所有书籍
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

    # 自定义方法:获取热门书籍
    def get_hot_books(self, request):
        hot_books = Book.objects.filter(is_hot=True)
        serializer = BookSerializer(hot_books, many=True)
        return Response(serializer.data)

步骤2:手动绑定路由

在urls.py里指定请求方法对应的自定义方法:

from django.urls import path
from .views import BookAPIView

urlpatterns = [
    path('books/', BookAPIView.as_view()),
    # 将GET请求绑定到get_hot_books方法
    path('books/hot/', BookAPIView.as_view({'get': 'get_hot_books'})),
]

内容的提问来源于stack exchange,提问作者Sahil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 11:02:33