Guide
Implementing Custom Pagination in Django REST Framework
Add a custom pagination class in Django REST Framework that lets clients set page size via a query parameter, with setup, testing, and rollback steps.
Published by Tasadduq Burney
19 Dec 2025, 18:02 UTC
2 min142.6K views0

Desired Outcome
Create a reusable pagination class that lets API clients control the number of items per page via a query parameter while preserving stable ordering.
Prerequisites
- Django ≥ 3.2 installed in a virtual environment.
- djangorestframework ≥ 3.12 installed.
- REST framework added to
INSTALLED_APPSinsettings.py. - An existing model, serializer, and viewset (or APIView) that returns a queryset.
Procedure
- Define the pagination class in a file, e.g.,
myapp/pagination.py:from rest_framework.pagination import PageNumberPagination class MyPagination(PageNumberPagination): # Default page size; can be overridden by client query param page_size = 5 page_size_query_param = 'page_size' max_page_size = 100 # optional safety limit def get_page_size(self, request): # Ensure the value is an integer and within bounds try: return int(request.query_params.get(self.page_size_query_param, self.page_size)) except (TypeError, ValueError): return self.page_size - Apply the pagination to a viewset. For a ModelViewSet:
from rest_framework import viewsets from .models import MyModel from .serializers import MyModelSerializer from .pagination import MyPagination class MyModelViewSet(viewsets.ModelViewSet): queryset = MyModel.objects.all().order_by('id') # stable ordering serializer_class = MyModelSerializer pagination_class = MyPagination - Alternatively set it globally in
settings.py:REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'myapp.pagination.MyPagination', 'PAGE_SIZE': 5 } - Run the development server:
python manage.py runserver - Test the endpoint with query parameters, e.g.,
GET /api/mymodels/?page=2&page_size=10and verify the JSON response containscount,next,previous, andresultskeys, and that the length ofresultsmatches the requested page size (or fewer on the final page).
Expected Checks
- HTTP status 200 OK.
- Response JSON includes pagination metadata.
- Changing
pageandpage_sizeyields different slices of the ordered queryset. nextandpreviousURLs are null when on the first or last page respectively.- Setting
page_sizeabovemax_page_sizefalls back to the limit.
Recovery Options
If pagination behaves incorrectly (e.g., missing fields or unexpected page sizes):
- Temporarily replace
pagination_class = MyPaginationwith the defaultfrom rest_framework.pagination import PageNumberPaginationor delete the attribute to fall back to the global default. - Restart the development server.
- Re‑run the test request to confirm the API returns the standard DRF pagination format.
- After verifying the issue is resolved, re‑introduce the custom class and adjust the implementation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.