Django Rest Framework Customize Pagination

Customize your pagination and return more data in API response for List View
Install Django Rest Framework by pip install djangorestframework
or pipenv install djangorestframework
Create a new Model Serializer in app/api/serializers.py
file like:
# app/api/serializers.py
from rest_framework import serializers
from app.models import Blog
class BlogSerializer(serializers.ModelSerializer):
class Meta:
model = Blog
fields = '__all__'

Create a new Model ViewSet in app/api/viewsets.py
like:

app/api/viewsets.py
# app/api/viewsets.py
class BlogViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated, ] # remove if not required
authentication_classes = [JWTAuthentication, SessionAuthentication] # remove if not required
serializer_class = BlogSerializer
queryset = Blog.objects.all()
Now Create a pagination class in app/api/paginations.py
like:
# app/api/paginations.py
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Responseclass CustomPagination(PageNumberPagination):
pass

app/api/paginations.py
Now add default pagination class in Django Settings for Rest Framwork
# project/settings.py
# default setup
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20
}# change default pagination class to you custom class
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'app.api.paginations.CustomPagination',
'PAGE_SIZE': 20 # we can make it dynamic from class. But, set a number as default
}

Now we will add more option in Pagination class. Default example response will be like
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?page=5",
"previous": "https://api.example.org/accounts/?page=3",
"results": [
…
]
}
Here is my full custom pagination class
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
import math
## you can override page_size, max_page_size from url query params \
## to make it more dynamic
class CustomPagination(PageNumberPagination):
page_size = 20 # default page size
max_page_size = 1000 # default max page size
page_size_query_param = 'page_size' # if you want to dynamic items per page from request you must have to add it
def get_paginated_response(self, data):
# if you want to show page size in resposne just add these 2 lines
if self.request.query_params.get('page_size'):
self.page_size = int(self.request.query_params.get('page_size'))
# you can count total page from request by total and page_size
total_page = math.ceil(self.page.paginator.count / self.page_size)
# here is your response
return Response({
'count': self.page.paginator.count,
'total': total_page,
'page_size': self.page_size,
'current': self.page.number,
'previous': self.get_previous_link(),
'next': self.get_next_link(),
'results': data
})

You can set this pagination class for all as default from settings file or you can use it to you viewsets and list views.
class BlogViewSet(viewsets.ModelViewSet):
serializer_class = BlogSerializer
queryset = Blog.objects.all()
pagination_class = CustomPagination

That’s it.
It should work now. If you need any help with Django let me know
Visit: imtipu.me
Thanks!