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
yields 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. I did notice that model viewsets have this method:
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. Any help would be great thanks!
CodePudding user response:
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()
CodePudding user response:
According to their docs you could use a regex lookup field. Their example uses a CBV instead of a request based view.
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