This is an advanced subject, do not attempt without first understanding the other examples of this page.
As stated in the official Django Rest Framework on pagination:
Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular APIView, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the mixins.ListModelMixin and generics.GenericAPIView classes for an example.
But what if we want to use pagination on a non generic view/viewset?
Well let's go down the rabbit hole:
First stop is the official Django Rest Framework's repository and specifically the
django-rest-framework/rest_framework/generics.py. The specific line this link is pointing at, shows us how the developers of the framework deal with pagination in their generics.
That is exactly what we are going to use to our view as well!
Let's assume that we have a global pagination setup like the one shown in the introductory example of this page and lets assume as well that we have an APIView
which we want to apply pagination to.
Then on views.py
:
from django.conf import settings
from rest_framework.views import APIView
class MyView(APIView):
queryset = OurModel.objects.all()
serializer_class = OurModelSerializer
pagination_class = settings.DEFAULT_PAGINATION_CLASS # cool trick right? :)
# We need to override get method to achieve 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)
... Do other stuff needed (out of scope of pagination)
# Now add the pagination handlers taken from
# django-rest-framework/rest_framework/generics.py
@property
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
else:
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)
Now we have an APIView
that handles pagination!