Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using custom methods in filter with django-rest-framework

I would like to filter against query params in my REST API - see django docs on this. However, one parameter I wish to filter by is only available via a model @property

example models.py:

class Listing(models.Model):
    product = models.OneToOneField(Product, related_name='listing')
    ...
    @property
    def category(self):
        return self.product.assets[0].category.name

Here is the setup for my Listing API in accordance with django-filter docs

    class ListingFilter(django_filters.FilterSet):
        product = django_filters.CharFilter(name='product__name')
        category = django_filters.CharFilter(name='category') #DOES NOT WORK!!

        class Meta:
            model = Listing
            fields = ['product','category']

    class ListingList(generics.ListCreateAPIView):
        queryset = Listing.objects.all()
        serializer_class = ListingSerializer
        filter_class = ListingFilter

How can I appropriately filter by listing.category? It is not available on the listing model directly.

like image 346
tomcounsell Avatar asked Jun 25 '14 17:06

tomcounsell


People also ask

How do I filter Queryset in Django REST framework?

The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the . get_queryset() method. Overriding this method allows you to customize the queryset returned by the view in a number of different ways.

What is the purpose of filter () method in Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.


1 Answers

Use the 'action' parameter to specify a custom method - see django-filter docs

First define a method that filters a queryset using the value of the category parameter:

    def filter_category(queryset, value):
        if not value:
            return queryset

        queryset = ...custom filtering on queryset using 'value'...
        return queryset

Listing filter should look like this:

    class ListingFilter(django_filters.FilterSet):
        ...
        category = django_filters.CharFilter(action=filter_category)
        ...
like image 136
tomcounsell Avatar answered Oct 11 '22 00:10

tomcounsell