Search code examples
django-rest-frameworkdrf-queryset

How to write the functionality in generics.ListAPIView which can be written in APIView in Django DRF


I have a function base view which get 2 parameters from URL http://127.0.0.1:8000/api/v1/contest/0b36d92a-51a7-4752-9df1-e5f2733116c1/paintings/

@api_view(['GET',])
@permission_classes([AllowAny])
def Contest_detail_by_id_and_category(request, id, category_name):
 
    if request.method == 'GET':
        
        artcontests = Artwork.objects.filter(artcontest = id,category__name__iexact=category_name)
        serializer = ArtworkSerializer(artcontests, many=True)
        # serializer = ArtworkSerializer(artcontests, many=True)
        return Response(serializer.data)

which give proper result , but when I try to write the same functionality in generics.ListAPIView it gives

TypeError at /api/v1/contesty/0b36d92a-51a7-4752-9df1-e5f2733116c1/paintings/ object of type 'method' has no len()

class Contest_detail_by_id_category(generics.ListAPIView):

 
    serializer_class = ArtworkSerializer1(many=True)
    permission_classes = [AllowAny]
    
    def queryset(self):
 
        queryset = Artwork.objects.filter(artcontest = self.kwargs['id'],category__name__iexact=self.kwargs['category_name'])
     
        # queryset = self.get_queryset()
        serializer = ArtworkSerializer1(queryset)
        return Response(serializer.data)

Can anyone help me - how to write the correct view in generics.ListAPIView or viewsets.ModelViewSet


Solution

  • Remove many=True from serializer_class. Create get_queryset function as below, instead of your queryset function.

    class Contest_detail_by_id_category(generics.ListAPIView):
    
        serializer_class = ArtworkSerializer1
        queryset = Artwork.objects.all()
        permission_classes = [AllowAny]
        
        def get_queryset(self):
            return self.queryset.filter(artcontest = self.kwargs['id'],category__name__iexact=self.kwargs['category_name'])
         
    

    Update: Working: ListAPIView class inherits ListModelMixin.

    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)
    

    See here. https://github.com/encode/django-rest-framework/blob/master/rest_framework/mixins.py