I would like to specify a custom lookup field on the action (different from the viewset default “pk”), i.e.
@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:
router = DefaultRouter() router.register(r"test", TestViewSet) router.urls
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. I did notice that model viewsets have this method:
but am unsure how to get it to be called to generate custom urls or if it is even relevant. 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.
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. (so consumers can use /test/?uuid= to retrieve data)
But if you really want to do it, you can simply override
get_object method to filter for your custom action tho:
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()
Here is a bit hacky solution for generate uuid in router with detail=False.
@action(detail=False, url_path=r'(?P<uuid>[^/.]+)/do_something') def do_something(self, request, uuid=None): pass