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

Django DRF使用@action(detail=True)触发pk组重定义错误的原因?

问题原因解析

核心触发点:URL路由重复匹配导致pk命名组冲突

你的urls.py存在重复包含路由的错误,结合detail=True的@action装饰器的路由生成规则,就触发了命名组重复定义的问题:

  1. DefaultRouter注册doctor视图集后,会自动生成两类基础路由:
    • 列表路径:/viewset/doctor/
    • 详情路径:/viewset/doctor/<int:pk>/
  2. 当你给verify方法加detail=True的@action装饰器时,DRF会额外生成一个带pk参数的详情动作路由:/viewset/doctor/<int:pk>/verify/
  3. 但你在urlpatterns里重复写了两次include(router.urls),第二次的前缀是path('viewset/<int:pk>', include(router.urls)),这就导致所有router生成的路由,都会多套一层你手动加的<int:pk>参数:
    • 原本的详情路由会变成:/viewset/<int:pk>/doctor/<int:pk>/
    • 额外的verify动作路由会变成:/viewset/<int:pk>/doctor/<int:pk>/verify/
      Django的URL解析器不允许同一条路由里出现同名的命名组,两个路由参数都叫pk,所以直接抛出重定义错误。

为什么去掉detail=True就正常了?

当你把detail=True移除后,verify变成列表级动作,生成的路由是/viewset/doctor/verify/,不会带第二层<int:pk>参数,也就不会出现两个pk命名组冲突的情况,但这时候你的verify方法本来是要操作单个doctor实例的,改成detail=False之后功能不符合预期。

修复方案

直接删除urls.py里重复的那行路由即可,修改后urlpatterns如下:

router = DefaultRouter()
router.register('doctor', views.DoctorViewSet, basename='doctor')

urlpatterns = [
    path('viewset/', include(router.urls)),
    # 删掉下面这行重复包含路由的代码
    # path('viewset/<int:pk>', include(router.urls)),
]

修改后两类路径都可以正常访问:

  • 单实例详情路径:/app_api/viewset/doctor/6/
  • 验证动作路径:/app_api/viewset/doctor/6/verify/(支持PATCH方法更新is_verified字段)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 10:27:05