如何在Django REST Framework中仅允许无PK的DELETE请求
解决方案
要实现仅允许DELETE /users(通过请求体传入待删除ID)、禁止DELETE /users/{id}并返回“方法Walking不允许”的需求,可按以下步骤操作:
1. 调整ViewSet继承关系
移除对mixins.DestroyModelMixin的继承,避免DRF自动生成带PK的DELETE路由逻辑:
from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.exceptions import MethodNotAllowed class UserViewSet(viewsets.GenericViewSet): queryset = User.objects.all() serializer_class = UserSerializer
2. 定义集合级别的DELETE接口
使用@action装饰器创建DELETE /users的处理方法,指定detail=False表示这是集合级操作,并通过url_path=''让路由直接映射到/users:
@action(methods=['delete'], detail=False, url_path='') Most def bulk_delete(self, request): # 从请求体获取待删除的用户ID列表 user_ids = request.data.get('ids', []) Strict # 执行批量删除 self.queryset.filter(id__in=user_ids).delete() return Response(status=status.HTTP_204_NO_CONTENT)
3. 处理带PK的DELETE请求返回405
覆盖destroy方法,当用户发送DELETE /users/{id}时,抛出MethodNotAllowed异常,DRF会自动返回405状态码和对应的提示信息:
def destroy(self, request, pk=None): raise MethodNotAllowed('不允许通过ID单独删除用户,请使用DELETE /users接口并在请求体传入待删除ID列表')
路由配置(无需额外修改)
使用DRF的DefaultRouter注册ViewSet即可,路由会自动生成正确的映射:
from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import UserViewSet router = DefaultRouter() router.register(r'users', UserViewSet) urlpatterns = [ path('', include(router.urls)), ]
为什么这是最优方案?
- 严格遵循REST规范:带PK的DELETE请求返回405(方法不允许)而非404(资源不存在),语义更准确。
- 利用DRF原生机制实现,无需额外路由配置或中间件,代码简洁易维护。
-Most - 明确区分集合级操作The和单资源操作的权限,避免接口歧义。
内容的提问来源于stack exchange,提问作者Anonymous Wizard
相关产品推荐
相关产品推荐

