0

I try to implement some basic filtering on my GenericAPIView, like this:

  • view:

    class OperatorList(generics.GenericAPIView):
    
        permission_classes = (permissions.IsAuthenticated, IsAdmin)
    
        filter_class = OperatorsFilter
        serializer_class = OperatorSerializer
    
        def get_queryset(self):
            queryset = self.request.user.operators.all()
    
        def get(self, request, *args, **kwargs):
            serializer = OperatorSerializer(instance=self.get_queryset(),
                                        many=True,
                                        context=self.get_serializer_context())
            return Response(serializer.data)
    
  • serializer:

    class OperatorSerializer(serializers.ModelSerializer):
        class Meta:
            model = Operator
            fields = ['id', 'name', 'created', ]
    
  • filter set:

    import rest_framework_filters
    from rest_framework import filters
    from .models import Operator
    
    
    class OperatorFilter(filters.FilterSet):
    
        created = rest_framework_filters.DateTimeField(lookup_type='gte')
    
        class Meta:
            model = Operator
            fields = ('name', 'created', )
    

The issue is that filters are displayed in browsable API, but 'Created' is not a DateTimeWidget, but a simple input. Also, applying filter takes no effect, and I still have to catch request.query_params in get_queryset() (I ama trying to use filter backend to avoid this in first turn).

Does anybody have any suggestions?

1 Answer 1

1

The problem here is that you've subclassed GenericAPIView and then not (re-)implemented any of the handy logic that Django REST Framework provides in its concrete view class.

Instead you want to subclass ListAPIView which provides a get method implementing the filtering behaviour you're looking for.

The magic all resides in ListModelMixin which filters the queryset as needed...

class ListModelMixin(object):
    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        ... method continues ...

Your final view class should then look something like this:

class OperatorList(generics.ListAPIView):

    permission_classes = (permissions.IsAuthenticated, IsAdmin)

    filter_class = OperatorsFilter
    serializer_class = OperatorSerializer

    def get_queryset(self):
        queryset = self.request.user.operators.all()

I hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm glad. PPs on the docs to improve them are ALWAYS welcomed :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.