7

I have a Viewset which has the following list method:

class PolicyViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Policy.objects.all()
        serializer = PolicySerializer(queryset, many=True)
        return Response(serializer.data)

This works as intended and I get my desired Response.However, now I am trying to limit the objects returned per GET request and for that I am using pagination.I have defined the following in the settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20
}

The docs say:

Pagination is only performed automatically if you're using the generic views or viewsets.

However, my result is still not paginated.What else do I need to do to enable pagination ?

M.javid
  • 6,387
  • 3
  • 41
  • 56
Amistad
  • 7,100
  • 13
  • 48
  • 75
  • Possible duplicate of [Django Rest Framework: turn on pagination on a ViewSet (like ModelViewSet pagination)](https://stackoverflow.com/questions/31785966/django-rest-framework-turn-on-pagination-on-a-viewset-like-modelviewset-pagina) – Abdul Niyas P M Feb 07 '19 at 05:39
  • the answers for that involve using a genericViewset..However, I want the solution with a normal Viewset – Amistad Feb 07 '19 at 05:48

2 Answers2

18

If you overwrite your list or any main method you need to explicitly called for that.

class PolicyViewSet( viewsets.GenericViewset):
    def list(self, request):
        queryset = Policy.objects.all()
        page = self.paginate_queryset(queryset)
        serializer = PolicySerializer(page, many=True)
        return self.get_paginated_response(serializer.data)
Shakil
  • 4,520
  • 3
  • 26
  • 36
  • i tried this but now i get the error..'PageNumberPagination' object has no attribute 'page'.. – Amistad Feb 07 '19 at 05:47
  • @Amistad i have updated my code. sorry for previous one. you can check now. hope this will work :) – Shakil Feb 07 '19 at 05:50
  • also..can you let me know if i create a custom paginator per viewset..how do I use that in my viewset ? – Amistad Feb 07 '19 at 05:52
  • @Amistad two way you can do that. you can overwrite `pagination_class` class or if these is just number of response vary from request to request, you can simple send a limit from frontend. Say '/users/' will give you paginator response from you default set value but if you request like '/users/?limit=30' then it will give you response 30 users per page. – Shakil Feb 07 '19 at 06:05
  • 1
    @Shakil..actually this works only with a viewsets.GenericViewset and not a viewsets.Viewset..with just a Viewset, it gives an error stating 'PolicyViewSet' object has no attribute 'paginate_queryset'.. – Amistad Feb 15 '19 at 05:41
  • 1
    @Amistad i have worked with model.Viewsets that also work fine. I updated the correct inheritance. Thanks to point this out for future help seekers. – Shakil Feb 15 '19 at 07:25
0

You can use either GenericViewSet or ModelViewSet(as its also inherited from GenericViewSet).

Using GenericViewSet or ModelViewSet

# or class PolicyViewSet(viewsets.GenericViewSet):
class PolicyViewSet(viewsets.ModelViewSet):

    def list(self, request):
        queryset = Policy.objects.all()
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = PolicySerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        else:
            serializer = PolicySerializer(queryset, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

Using ViewSet

class PolicyViewSet(viewsets.ViewSet):

    def list(self, request):
        from rest_framework.pagination import PageNumberPagination
        queryset = Policy.objects.all()
        paginator = PageNumberPagination()
        page = paginator.paginate_queryset(queryset, request)
        if page is not None:
            serializer = PolicySerializer(page, many=True)
            return paginator.get_paginated_response(serializer.data)
        else:
            serializer = PolicySerializer(queryset, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
Umar Asghar
  • 3,808
  • 1
  • 36
  • 32