[Fixed]-How to use Pagination in a Non-Generic View/Viewset?


We can find a solution without the need to reinvent the wheel:

  1. Let’s have a look on how the generics pagination is implemented:
    That is exactly what we are going to use to our view as well!

  2. Let’s assume that we have a global pagination setup like the following in:


        'PAGE_SIZE': 100
  3. In order not to bloat our view/viewset’s code, we can create a custom mixin to store our pagination code:

    class MyPaginationMixin(object):
        def paginator(self):
            The paginator instance associated with the view, or `None`.
             if not hasattr(self, '_paginator'):
                 if self.pagination_class is None:
                     self._paginator = None
                     self._paginator = self.pagination_class()
             return self._paginator
         def paginate_queryset(self, queryset):
             Return a single page of results, or `None` if pagination 
             is disabled.
             if self.paginator is None:
                 return None
             return self.paginator.paginate_queryset(
                 queryset, self.request, view=self)
         def get_paginated_response(self, data):
             Return a paginated style `Response` object for the given 
             output data.
             assert self.paginator is not None
             return self.paginator.get_paginated_response(data)
  4. Then on views.py:

    from rest_framework.settings import api_settings
    from rest_framework.views import APIView
    from my_app.mixins import MyPaginationMixin
    class MyView(APIView, MyPaginationMixin):
        queryset = OurModel.objects.all()
        serializer_class = OurModelSerializer
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS 
        # We need to override the get method to insert pagination
        def get(self, request):
            page = self.paginate_queryset(self.queryset)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)

And now we have an APIView with pagination.

Leave a comment