用 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

我们知道,当ModelViewSetDefaultRouter 一起使用时,会在 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/&lt;str:device&gt;/&lt;str:start_time&gt;/.

更多玩,我了解到在我的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/&lt;str:device&gt;/&lt;str:start_time&gt;/.

有两个蛞蝓,没有改变我的观点的基类,即ModelViewSet。我知道我想要的功能可以通过GenericAPIView 轻松完成,我也做到了,但我很好奇如何做到这一点。

【问题讨论】:

如果您保留lookup_fields = ["device", "start_time"] 但使用router.register(r'' 会发生什么? @bdbd 更改最后一个 slug 即“pk”,我们不仅需要在字典中添加 kwargs_urllookup_field,还需要在视图中添加完全相同的 lookup_field。这就是为什么我将视图中的lookup_fields 更改为lookup_field,并将其值更改为startup_time。如果它们不匹配,则 URL 保持原样:mydomain.com/viewset/&lt;str:device&gt;/&lt;str:start_time&gt;/organization/&lt;int:pk&gt;/ 如果我在 extra_kwargs 中添加 lookup_fieldsextra_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的主要内容,如果未能解决你的问题,请参考以下文章

MS Access 在多个表的列字段中查找和替换文本

如何在一个类的每个请求中使用不同的查找字段

ModelViewSet - 更新嵌套字段

Eclipse 用正则表达式查找/替换整行

我需要用次要条件在 SQL 表中查找/替换值

linux命令应用