如何在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
相关产品推荐
相关产品推荐

