anttikoo
anttikoo

Reputation: 815

Secondary fetch endpoint with Django Rest Framework

I have the following viewset:

class ProductViewSet(
        mixins.RetrieveModelMixin,
        viewsets.GenericViewSet):
    ...

This provides me with endpoint for fetching a product by ID:

/products/{id}

I'm trying to add another endpoint for fetching a product with secondary unique key (uuid), so that I will have the following endpoints:

# Existing endpoint, lookup by ID. This I have, and want to keep.
/products/{product_id}  

# Additional endpoint, lookup by UUID. This is what I'm trying to add.
/products/uuid/{product_uuid}

So API consumer must be able to look up a product by either ID or UUID.

How can I achieve this with DRF? I'm using DRF 3.8.2 and Django 1.11.

Is it somehow possible to make @action() decorator provide this? Its basic behaviour does not solve the problem as it only provides urls of pattern /products/{id}/detail or /products/detail.

Upvotes: 2

Views: 360

Answers (1)

neverwalkaloner
neverwalkaloner

Reputation: 47364

For multiple lookup you can write mixin:

class MultipleFieldLookupMixin(object):
    """
    Apply this mixin to any view or viewset to get multiple field filtering
    based on a `lookup_fields` attribute, instead of the default single field filtering.
    """
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            if self.kwargs[field]: # Ignore empty fields.
                filter[field] = self.kwargs[field]
        obj = get_object_or_404(queryset, **filter)  # Lookup the object
        self.check_object_permissions(self.request, obj)
        return obj

And use it like this:

class ProductViewSet(MultipleFieldLookupMixin, 
            mixins.RetrieveModelMixin,
            viewsets.GenericViewSet):
        lookup_fields =( 'product_uuid', 'pk') 

more details in the docs

Upvotes: 1

Related Questions