Django Rest Framework Customize Pagination

Borhan Tipu
3 min readApr 30, 2021

--

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__'
app/api/serializers.py

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 Response
class 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
}
project/settings.py

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
})
CustomPagination class

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!

Sign up to discover human stories that deepen your understanding of the world.

--

--

Borhan Tipu
Borhan Tipu

Written by Borhan Tipu

Django Developer & Shopify Expert. Find me: imtipu.me

Responses (1)

Write a response