django filter on APIView

Serenity picture Serenity · May 11, 2017 · Viewed 8.8k times · Source

I have a APIView class for showing all the rents and posting and delete etc. Now i want search feature so i tried to use DjangoFilterBackend but it is not working. I see in documentation, it has been used with ListAPIView but how can i use it in APIView.

class Rent(APIView):
    """
    List all the rents if token is not provided else a token specific rent
    """
    serializer_class = RentSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('city', 'place', 'property_category',)
    search_fields = ('=city', '=place')
    def get(self, request, token=None, format=None):
        reply={}
        try:
            rents = Rental.objects.all()
            if token:
                rent = Rental.objects.get(token=token)
                reply['data'] = self.serializer_class(rent).data
            else:
                reply['data'] = self.serializer_class(rents, many=True).data
        except Rental.DoesNotExist:
            return error.RequestedResourceNotFound().as_response()
        except:
            return error.UnknownError().as_response()
        else:
            return Response(reply, status.HTTP_200_OK)

when i search the rent with the following parameters in the url, i get all the rents, instead i should get only those rents that lies in city Kathmandu and place koteshwor

http://localhost:8000/api/v1/rents?city=Kathmandu&place=Koteshwor

Answer

ChidG picture ChidG · May 11, 2017

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