Search code examples
djangodjango-rest-frameworkdjango-filter

Django | REST | Add of top level JSON field breaks filtering option


I have to work ListAPIView view, via which I can filter via django-filter values. But I need to add an object in JSON (because AMP HTML needs that) and when I add this, It will break this filtering.

When I use this view, filtering is works great:

class TypeAPIView(generics.ListAPIView):
    permission_classes = (AllowAny, )
    queryset = Type.objects.all()
    serializer_class = TypeSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ('code', )


    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

But when I want to add a top level JSON object, it will breaks a filtering option:

class TypeAPIView(generics.ListAPIView):
    permission_classes = (AllowAny, )
    queryset = Type.objects.all()
    serializer_class = TypeSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ('code', )


def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())
    serializer = self.get_serializer(queryset, many=True)
    # --- modified from here ---
    custom_data = {
        'vehicles': serializer.data
    }
    return Response(custom_data)
    # --- END modified from here ---

Is possible to add a top-level JSON object and keep the filtering of django-filter working?

Thank you!


Solution

  • This code is taken from django source code:

    class ListModelMixin:
        """
        List a queryset.
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    

    Try to use this format and add the tracklog from your terminal.