28👍
✅
We can find a solution without the need to reinvent the wheel:
-
Let’s have a look on how the
generics
pagination is implemented:
django-rest-framework/rest_framework/generics.py.
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 following in:
settings.py
:REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.DESIRED_PAGINATION_STYLE', 'PAGE_SIZE': 100 }
-
In order not to bloat our view/viewset’s code, we can create a custom mixin to store our pagination code:
class MyPaginationMixin(object): @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)
-
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.
Source:stackexchange.com