I have multiple API which historically work using id
as the lookup field:
/api/organization/10
I have a frontend consuming tho
I think best way is to override the get_object(self)
method
class Organization(generics.RetrieveAPIView):
serializer_class = OrganizationSerializer
queryset = Organization.objects.all()
multiple_lookup_fields = ['pk', 'slug']
def get_object(self):
queryset = self.get_queryset()
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)
return obj
I know you asked this question quite a time ago, but here is the complete solution i got from all answers, considering both views and urls:
Put this in your views.py: (With a little edit from drf)
class MultipleFieldLookupMixin(object):
def get_object(self):
queryset = self.get_queryset()
queryset = self.filter_queryset(queryset)
filter = {}
for field in self.lookup_fields:
if self.kwargs.get(field, None):
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter) # Lookup the object
self.check_object_permissions(self.request, obj)
return obj
Then inherit your view from this Mixin and add fields you want to lookup_fields. Like this:
class YourDetailView(MultipleFieldLookupMixin, RetrieveUpdateAPIView):
...
lookup_fields = ['pk', 'slug','code']
And in urls.py:
re_path(r'^organization/(?P<pk>[0-9]+)/$',
YourDetailView),
re_path(r'^organization/(?P<slug>[-a-zA-Z0-9_]+)/$',
YourDetailView),
re_path(r'^organization/sth_else/(?P<code>[0-9]+)/$',
YourDetailView),