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?
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.
The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.
Filtering backend allow you to achieve various filtering (search, ordering etc.) with writing just a line of code (that is enabling the filter backend). You could achieve the same result by not using any filter backend and instead filtering yourself using the query parameter.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With