Search code examples
django-rest-frameworkdjango-pagination

Pagination query query duplicated, why is the query more than once?


Why is the query duplicated?, Is there anything I haven't noticed?

Is there any way this can be optimized?

Pagination

class MyPageNumberPagination(PageNumberPagination):
    page_size = 2
    page_size_query_param = 'size'
    max_page_size = 4

    def get_paginated_response(self, data):
        return Response({
            'page': self.page.number,
            'total_pages': self.page.paginator.num_pages,
            'count': self.page.paginator.count,
            'data': data
        })

enter image description here

Views Do not use pagination.

class DevicesView(ModelViewSet):
    serializer_class = DeviceSerializer
    queryset = DeviceModel.objects.all()

    def list(self, request, *args, **kwargs):
        queryset = DeviceModel.objects.filter(owner_id__owner__id=request.user.pk)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

Views Use pagination.

enter image description here

class DevicesView(ModelViewSet):
    serializer_class = DeviceSerializer
    queryset = DeviceModel.objects.all()
    pagination_class = MyPageNumberPagination

    def list(self, request, *args, **kwargs):
        queryset = DeviceModel.objects.filter(owner_id__owner__id=request.user.pk)
        page = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

Solution

  • You are accessing queryset two times. One paginating, and one for just serializer:

    page = self.paginate_queryset(queryset) # <---- Hits DB
    serializer = self.get_serializer(queryset, many=True) # <---- Hits DB again
    

    You should pass page to your serializer:

    serializer = self.get_serializer(page, many=True)