Juan Torres
Juan Torres

Reputation: 744

Using filters with list_routes in drf

Is there a way to use filters for @list_route the same way you use them for the root ViewSet in DRF?

I have a model that I have configured filters for and a detail route that I cannot:

class ListingViewSet(viewsets.ModelViewSet):
    # disable listing after 5 flags
    queryset = Listing.objects.all()

    serializer_class = ListingSerializer
    filter_backends = (DjangoFilterBackend, OrderingFilter, SearchFilter)
    permission_classes = (ListingOwnerCanEdit,)
    filter_class = ListingFilter

    @list_route()
    def homepage(self, request):
        queryset = Listing.objects.filter(flags__lt=5, closed=False)

        ### Doesn't work
        # filter_backends = (DjangoFilterBackend, OrderingFilter, SearchFilter)
        # permission_classes = (ListingOwnerCanEdit,)
        # filter_class = ListingFilter
        # ordering_filter = OrderingFilter()
        # ordering_fields = ('price', 'views')
        # search_fields = ('title', 'description')

        serializer = ListingSerializer(queryset, many=True, context=self.get_serializer_context())
        return Response(serializer.data)

And ListingFilter is:

class ListingFilter(django_filters.rest_framework.FilterSet):
    min_price = django_filters.NumberFilter(name="price", lookup_expr='gte')
    max_price = django_filters.NumberFilter(name="price", lookup_expr='lte')
    author_pk = django_filters.CharFilter(name='author_pk')

    class Meta:
        model = Listing
        fields = ['price_type', 'sale_type', 'category__name', 'min_price', 'max_price', 'description', 'title',
              'listing_date', 'views', 'number_of_inquiries', 'author_pk', 'closed', 'closing_date']

Is there a way to use ListingFilter with the homepage list route?

Upvotes: 6

Views: 2012

Answers (1)

pchiquet
pchiquet

Reputation: 3187

You should call filter_queryset in your method decorated with @list_route:

@list_route()
def homepage(self, request):
    queryset = self.get_queryset().filter(flags__lt=5, closed=False)
    queryset = self.filter_queryset(queryset)

    serializer = ListingSerializer(queryset, many=True, context=self.get_serializer_context())
    return Response(serializer.data)

Edit: it is also a good idea to use self.get_queryset() instead of Listing.objects.

Upvotes: 9

Related Questions