用 ModelViewSet 的多个查找字段替换 Default PK slug
Posted
技术标签:
【中文标题】用 ModelViewSet 的多个查找字段替换 Default PK slug【英文标题】:Replace Default PK slug with Multiple Lookup Fields for ModelViewSet 【发布时间】:2021-10-02 17:16:39 【问题描述】:我有两个蛞蝓,我针对它们运行查询。感谢基类MultipleFieldLookupMixin
,我的视图类继承自它,因此允许我拥有多个lookup_fields
。
我们知道,当ModelViewSet
与DefaultRouter
一起使用时,会在 URL 的末尾附加一个 pk
,我不希望这样做。
例如,当我这样做时:
router = DefaultRouter()
router.register(r'organization', OrganizationModelViewSet, basename='organization')
urlpatterns = [
path('viewset/<str:device>/<str:start_time>/', include(router.urls))
]
它给了我网址
mydomain.com/viewset/<str:device>/<str:start_time>/organization/<int:pk>/
最后我不想要这个pk
。如果我们可以删除organization
,那就更好了。我希望端点是,
mydomain.com/<str:device>/<str:start_time>/
.
更多玩,我了解到在我的serializer
类中添加这样的extra_kwargs
,
extra_kwargs =
'url': 'lookup_field': 'start_time'
并修改视图类中的lookup_fields
,使用奇异的查找字段,如lookup_field
,并设置值为start_time
,如图所示
lookup_fields = ["device", "start_time"]
与
lookup_field = "start_time"
并通过删除start_time
slug相应地修改URL,然后URL变为
mydomain.com/viewset/<str:device>/organization/<str:start_time>/
用start_time
修改单数lookup_field
,显然或多或少地为我们提供了所需的URL,但没有完成工作,因为我们现在只有一个lookup_field!
如果我们编辑这一行
router.register(r'organization', DeviceActivityModelViewSet, basename='device_activity')
到
router.register(r'', DeviceActivityModelViewSet, basename='device_activity')
然后我们得到网址
mydomain.com/viewset/<str:device>/<str:start_time>/
这正是我想要的,但正如我所说,它不起作用,因为单个查找字段。
切入正题,我希望它能澄清我对此的研究,并重申我想要拥有此 URL 端点的问题陈述
mydomain.com/<str:device>/<str:start_time>/
.
有两个蛞蝓,没有改变我的观点的基类,即ModelViewSet
。我知道我想要的功能可以通过GenericAPIView
轻松完成,我也做到了,但我很好奇如何做到这一点。
【问题讨论】:
如果您保留lookup_fields = ["device", "start_time"]
但使用router.register(r''
会发生什么?
@bdbd 更改最后一个 slug 即“pk”,我们不仅需要在字典中添加 kwargs_url
和 lookup_field
,还需要在视图中添加完全相同的 lookup_field
。这就是为什么我将视图中的lookup_fields
更改为lookup_field
,并将其值更改为startup_time
。如果它们不匹配,则 URL 保持原样:mydomain.com/viewset/<str:device>/<str:start_time>/organization/<int:pk>/
如果我在 extra_kwargs
中添加 lookup_fields
,extra_kwargs = 'url': 'lookup_fields': ['device', 'start_time']
它也不起作用,并且 URL 仍然如上所述
您可以添加MultipleFieldLookupMixin
定义吗?这听起来像是自定义路由器实现的完美用例。 django-rest-framework.org/api-guide/routers/#custom-routers
请出示OrganizationModelViewSet
的代码
【参考方案1】:
因为我不需要完整查看您的代码,所以我认为下面的代码 sn-p 应该适合您。
urlpatterns = [
path('/<str:device>/<str:start_time>/', include(router.urls))
]
如果没有成功,请告诉我
【讨论】:
以上是关于用 ModelViewSet 的多个查找字段替换 Default PK slug的主要内容,如果未能解决你的问题,请参考以下文章