[Fixed]-Django filter on APIView

11👍

Here If you are using APIView, There is nothing to do with filters.So you have to do like

get_data = request.query_params #or request.GET check both

Then

Rental.objects.filter(city=get_data['city'], place=get_data['place'])

15👍

To use the functionality of DjangoFilterBackend, you could incorporate the filter_queryset method from GenericViewSet, which is the DRF class that inherits from APIView and leads to all specific ‘generic’ view classes in DRF. It looks like this:

def filter_queryset(self, queryset):
    """
    Given a queryset, filter it with whichever filter backend is in use.
    You are unlikely to want to override this method, although you may need
    to call it either from a list view, or from a custom `get_object`
    method if you want to apply the configured filtering backend to the
    default queryset.
    """
    for backend in list(self.filter_backends):
        queryset = backend().filter_queryset(self.request, queryset, self)
    return queryset

https://github.com/encode/django-rest-framework/blob/master/rest_framework/generics.py

👤ChidG

8👍

In case someone is wondering how can we integrate django_filters filter_class with api_views:

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def filter_data(request, format=None):
    qs = models.YourModal.objects.all()

    filtered_data = filters.YourFilter(request.GET, queryset=qs)
    filtered_qs = filtered_data.qs
    ....
    return response.Ok(yourData)

2👍

Adding to @ChidG’s answer. All you need to do is override the DjangoFilterBackend’s filter_queryset method, which is the entry point for the filter, and pass it the instance of your APIView. The important point to note here is you must declare filter_fields or filter_class on the view in order to get the filter to work. Otherwise it just return your queryset unfiltered.

If you’re more curious about how this works, the class is located at django_filters.rest_framework.backends.py

In this example, the url would look something like {base_url}/foo?is_active=true

from django_filters.rest_framework import DjangoFilterBackend

class FooFilter(DjangoFilterBackend):

    def filter_queryset(self, request, queryset, view):
        filter_class = self.get_filter_class(view, queryset)

        if filter_class:
            return filter_class(request.query_params, queryset=queryset, request=request).qs
        return queryset

class Foo(APIView):

    permission_classes = (AllowAny,)
    filter_fields = ('name', 'is_active')

    def get(self, request, format=None):
        queryset = Foo.objects.all()

        ff = FooFilter()
        filtered_queryset = ff.filter_queryset(request, queryset, self)

        if filtered_queryset.exists():
            serializer = FooSerializer(queryset, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response([], status=status.HTTP_200_OK)

Leave a comment