Django中如何配置路由访问ViewSet内的指定方法
问题诊断与修复方案
认知错误纠正
你对DRF路由生成规则的认知确实存在偏差:
- DRF的
DefaultRouter不会为每个方法生成/前缀/方法名的独立端点,而是遵循RESTful规范,用HTTP方法匹配对应操作:- POST
/users/→ 对应create方法 - GET
/users/→ 对应list方法 - GET
/users/<pk>/→ 对应retrieve方法 - PUT/PATCH
/users/<pk>/→ 对应update方法 - DELETE
/users/<pk>/→ 对应destroy方法
- POST
- 如果要自定义额外的方法端点,需要用
@action装饰器标记方法,才会被router识别生成路由
现有代码的错误点
- UserViewSet未继承DRF的基类:普通类无法被router识别解析方法,必须继承
rest_framework.viewsets.ViewSet或其子类 - router生成的路由未加入urlpatterns:你只注册了viewset,但没有把router生成的路由规则加到Django的路由列表里
- 类装饰器使用错误:
@csrf_exempt不能直接装饰类,需要装饰类的dispatch方法,或者继承DRF基类后默认会处理CSRF验证(API请求一般用Token认证不需要CSRF) - ViewSet方法参数缺失:create方法必须接收request作为第一个参数,否则无法处理请求
修复后的代码示例
urls.py修改
from rest_framework.routers import DefaultRouter from users.views import UserViewSet, testing from django.urls import path router = DefaultRouter() router.register(r"users", UserViewSet, basename="users") urlpatterns = [ path('testing', testing), ] + router.urls # 把router生成的路由加到路由列表里
views.py修改
from rest_framework.viewsets import ViewSet from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator # 给类的dispatch方法加csrf_exempt,取消CSRF验证 @method_decorator(csrf_exempt, name='dispatch') class UserViewSet(ViewSet): # 对应POST请求访问 /users/ def create(self, request): return JsonResponse({ 'msg': 'the create endpoint' }) @csrf_exempt def testing(request): return JsonResponse({ "title": "My json res" })
访问验证
- 用POST方法请求
example.com/users/即可触发create方法,拿到返回结果 - 如果需要生成
/users/自定义方法名的端点,可以用@action装饰器:
from rest_framework.decorators import action @method_decorator(csrf_exempt, name='dispatch') class UserViewSet(ViewSet): def create(self, request): return JsonResponse({'msg': 'create endpoint'}) # 自定义端点,methods指定允许的请求方法,detail指定是否需要传pk参数 @action(methods=['get'], detail=False) def my_custom(self, request): return JsonResponse({'msg': 'custom endpoint'})
上面的自定义方法可以通过GET请求example.com/users/my_custom/访问。
内容的提问来源于stack exchange,提问作者StevenBoyce
相关产品推荐
相关产品推荐

