Search code examples
djangodjango-rest-frameworkdrf-yasg

get_queryset for ListCreateAPIView not being called


I have a ListCreateAPIView that I'm trying to override get_queryset, but it is never being called. Here is my view:

class DeviceView(generics.ListCreateAPIView):
    def get_queryset(self):
        # Threw this and some print statements, but no sign of 
        # the exception or print statement
        raise Exception
        return None
    @swagger_auto_schema(
        responses={
            201: DeviceSerializer(),
        },
        request_body=DeviceSerializer,
    )
    def post(self, request, format=None):
        # This code works fine
        ...
    @swagger_auto_schema(responses={200: DeviceSerializer(many=True)})
    def get(self, request, format=None):
        # This code DOES get hit and successfully retrieves all the devices

Here is the urls.py:

urlpatterns = [
    path(r"devices/<serialnumber>/abc", views.AbcView.as_view()),
    path(r"devices/<serialnumber>", views.DeviceDetailView.as_view()),
    path(r"devices/", views.DeviceView.as_view()),
    path(r"api-auth/", include("rest_framework.urls", namespace="rest_framework")),
    path(
        r"swagger/",
        schema_view.with_ui("swagger", cache_timeout=0),
        name="schema-swagger-ui",
    ),
    url(
        r"^swagger(?P<format>\.json|\.yaml)$",
        schema_view.without_ui(cache_timeout=0),
        name="schema-json",
    ),
    url(r"^api-token-auth/", obtain_jwt_token),
    path("admin/", admin.site.urls),
]

Any thoughts on why the get_queryset isn't being hit/overridden?


Solution

  • From the django rest framework code

    class ListAPIView(mixins.ListModelMixin,
                      GenericAPIView):
        """
        Concrete view for listing a queryset.
        """
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    

    So first, It is better to override the list function not the get.

    class ListModelMixin(object):
        """
        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)
    

    So you are probably missing the super call in list or the self.filter_queryset call. These will make sure that the get_queryset is called.