如何在Django REST API中仅允许自定义URL访问?
只开放自定义Action,屏蔽ViewSet默认CRUD路径的几种方案
如果你用DRF的ViewSet(尤其是ModelViewSet)时,默认会生成list、retrieve等CRUD对应的URL,要只保留自定义的get_all_users路径,有几个实用方法:
方案1:替换ViewSet基类,只保留自定义Action
ModelViewSet默认继承了所有CRUD的mixin类(ListModelMixin、RetrieveModelMixin等),所以会自动生成对应URL。换成GenericViewSet(保留序列化器、查询集等通用能力)或ViewSet(更轻量化),只添加你的自定义action,就能彻底去掉默认CRUD路径:
from rest_framework import viewsets from rest_framework.response import Response from .models import User from .serializers import UserSerializer class UserViewSet(viewsets.GenericViewSet): queryset = User.objects.all() serializer_class = UserSerializer @action(detail=False, methods=['get'], url_path='get_all_users') def get_all_users(self, request): users = self.get_queryset() serializer = self.get_serializer(users, many=True) return Response(serializer.data)
用router注册这个ViewSet后,只会生成/users/get_all_users/路径,默认的/users/、/users/<pk>/等路径不会存在。
方案2:在ModelViewSet中禁用默认HTTP方法
如果不想替换基类,直接在ModelViewSet里设置http_method_names = [],让默认的CRUDaction没有可访问的HTTP方法,这样用户访问/users/等路径会返回405 Method Not Allowed,只有自定义action能正常访问:
from rest_framework import viewsets from rest_framework.response import Response from .models import User from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer http_method_names = [] # 禁用所有默认CRUD的HTTP方法 @action(detail=False, methods=['get'], url_path='get_all_users') def get_all_users(self, request): users = self.get_queryset() serializer = self.get_serializer(users, many=True) return Response(serializer.data)
方案3:手动配置URL,不使用DRF Router
跳过DRF的自动路由生成,直接在urls.py里映射自定义action的视图,完全自己控制URL路径:
# urls.py from django.urls import path from .api import UserViewSet urlpatterns = [ path('get_all_users/', UserViewSet.as_view({'get': 'get_all_users'}), name='get_all_users'), ]
这种方式不需要用router,也不会生成任何默认CRUD路径,完全自定义URL结构。
内容的提问来源于stack exchange,提问作者Helguera
相关产品推荐
相关产品推荐

