简体   繁体   English

如何为视图集上的 DRF 操作指定自定义查找字段?

[英]How do I specify a custom lookup field for a DRF action on a viewset?

I would like to specify a custom lookup field on the action (different from the viewset default "pk"), ie我想在操作上指定一个自定义查找字段(不同于视图集默认的“pk”),即

@action(
        methods=["GET"],
        detail=True,
        url_name="something",
        url_path="something",
        lookup_field="uuid",  # this does not work unfortunately
    )
    def get_something(self, request, uuid=None):
         pass

But the router does not generate the correct urls:但路由器不会生成正确的 url:

router = DefaultRouter()
router.register(r"test", TestViewSet)
router.urls

yields url:产生 url:

'^test/(?P<pk>[^/.]+)/something/$'

instead of代替

'^test/(?P<uuid>[^/.]+)/something/$'

I do not want to change the lookup field for the whole viewset though and have been unsuccessful in finding a way to do this for the action itself after debugging through the router url generation.不过,我不想更改整个视图集的查找字段,并且在通过路由器 url 代进行调试后,未能成功地找到为操作本身执行此操作的方法。 I did notice that model viewsets have this method:我确实注意到 model 视图集有这个方法:

get_extra_action_url_map(self)

but am unsure how to get it to be called to generate custom urls or if it is even relevant.但我不确定如何调用它来生成自定义 url,或者它是否相关。 Any help would be great thanks!任何帮助都会非常感谢!

I think it will create much confusion for your API consumers if you have 2 different resource identification on the same resource.如果您在同一资源上有 2 个不同的资源标识,我认为这会给您的 API 消费者造成很多混乱。

You can name that action query_by_uuid or just allow them to use list_view to filter by uuid if you only want to represent the object tho.如果您只想表示 object tho,您可以将该操作命名为query_by_uuid ,或者只允许他们使用list_view来按uuid进行过滤。 (so consumers can use /test/?uuid= to retrieve data) (因此消费者可以使用 /test/?uuid= 来检索数据)

But if you really want to do it, you can simply override get_object method to filter for your custom action tho:但是,如果您真的想这样做,您可以简单地覆盖get_object方法来过滤您的自定义操作:

def get_object(self):
    if self.action == 'do_something':
        return get_object_or_404(self.get_queryset(), uuid=self.kwargs['pk'])
    return super().get_object()

According to their docs you could use a regex lookup field.根据他们的文档,您可以使用正则表达式查找字段。 Their example uses a CBV instead of a request based view.他们的示例使用 CBV 而不是基于请求的视图。

class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    lookup_field = 'uuid'
    lookup_value_regex = '[0-9a-f]{32}'

This could work:这可以工作:

@action(
        methods=["GET"],
        detail=True,
        url_name="something",
        url_path="something",
        lookup_field = 'uuid'
        lookup_value_regex = '[0-9a-f]{32}'
    )
    def get_something(self, request, uuid=None):
         pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM