pagination
Learn how to implement pagination in Django REST Framework for efficient API data handling. Covers generic views, viewsets, and APIView with code examples.
Django REST Framework Pagination
Implementing Pagination in Django REST Framework
Pagination is a crucial technique for managing large datasets in APIs, preventing performance issues and improving user experience. Django REST Framework (DRF) provides robust tools to implement pagination easily. This guide explains how to apply pagination effectively, whether you are using generic class-based views, viewsets, or custom APIView
.
Pagination with Generic Class-based Views and Viewsets
For generic class-based views and viewsets, DRF can automatically handle pagination. To enable this, you primarily need to configure your settings.py
file by overriding the DEFAULT_PAGINATION_CLASS
and PAGE_SIZE
settings.
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 20
}
This configuration sets LimitOffsetPagination
as the default pagination class, with each page containing 20 items. You can choose other pagination classes like PageNumberPagination
based on your needs.
Pagination with APIView or Non-Generic Views
When using APIView
or other non-generic views, pagination must be explicitly applied within the view itself. First, define the default pagination behavior in settings.py
as shown above.
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 20
}
Next, you need to integrate pagination logic into your APIView
. This involves setting the pagination_class
attribute and overriding the get
method to use the paginator.
from rest_framework.settings import api_settings
from rest_framework.views import APIView
from rest_framework.response import Response
class PostView(APIView):
# Assume queryset and serializer_class are defined elsewhere
# queryset = ...
# serializer_class = ...
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
def get(self, request):
# Apply pagination to the queryset
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)
# If pagination is disabled or not applicable
serializer = self.serializer_class(self.queryset, many=True)
return Response(serializer.data)
# Helper methods for pagination, typically found in generic views
@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."""
return self.paginator.get_paginated_response(data)
Customizing Pagination Classes
DRF allows you to create custom pagination classes to tailor pagination behavior. By extending existing pagination classes (like PageNumberPagination
), you can override default attributes such as page_size
, page_size_query_param
, and max_page_size
.
from rest_framework.pagination import PageNumberPagination
class CustomPagination(PageNumberPagination):
"""
Client controls the response page size (with query param), limited to a maximum of `max_page_size` and default of `page_size`.
"""
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 10000
You can then assign this CustomPagination
class to specific views or set it as the default in settings.py
.