Adding Pagination in APIs - Django REST Framework
Last Updated :
06 Dec, 2025
When a database contains a large number of records, retrieving all of them at once in a single HTTP GET request can be inefficient. Pagination in Django REST Framework (DRF) solves this problem by splitting the result set into pages. Each HTTP request can then fetch a specific page of data, along with metadata such as the total count, the next page, and the previous page. DRF provides several pagination styles i.e, PageNumberPagination, LimitOffsetPagination, CursorPagination.
The PageNumberPagination style accepts a single page number in the request query parameters to fetch a specific page of results.
To enable this pagination style globally, set rest_framework.pagination.PageNumberPagination as the DEFAULT_PAGINATION_CLASS in settings.py and define the desired PAGE_SIZE.
Python
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2,
}
The pagination style can be modified by overriding the attributes in the PageNumberPagination class. Key attributes include:
- django_paginator_class: Paginator class to use. Default: django.core.paginator.Paginator.
- page_size: Number of items per page. Overrides the PAGE_SIZE setting if set. Defaults to the value of PAGE_SIZE.
- page_query_param: Name of the query parameter used to specify the page number.
- page_size_query_param: Name of a query parameter that allows setting the page size per request. Defaults to None.
- max_page_size: Maximum allowable page size requested by the client. Only valid if page_size_query_param is set.
- last_page_strings: Used with page_query_param to request the final page. Defaults to ('last',).
- template: Template name for rendering pagination controls in the browsable API.
Adding Sample Data:
Additional robot records can be added to the database using HTTPie commands:
http POST :8000/robot/ name="M-10iD/8L" robot_category="Articulated Robots" currency="USD" price=20000 manufacturer="Fanuc" manufacturing_date="2020-02-12 00:00:00+00:00"
http POST :8000/robot/ name="SR-6iA" robot_category="SCARA Robots" currency="USD" price=10000 manufacturer="Fanuc" manufacturing_date="2020-02-12 00:00:00+00:00"
Retrieving Paginated Results
To fetch paginated results from the API:
http :8000/robot/
Output:

The response structure differs from a standard HTTP GET request. The keys included in the response are:
- count: Total number of resources across all pages.
- next: URL to the next page of results.
- previous: URL to the previous page of results.
- results: Array containing JSON representations of the individual instances.
Retrieving Page 2 Results:
To fetch the second page of results, use the following HTTPie command:
http :8000/robot/?page=2
Output:

In the LimitOffsetPagination style, the client provides both a limit and an offset query parameter:
- limit: Maximum number of items to return, equivalent to page_size.
- offset: Starting position in the unpaginated result set.
To enable this pagination style globally, set rest_framework.pagination.LimitOffsetPagination as the DEFAULT_PAGINATION_CLASS in settings.py:
Python
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2,
}
Setting PAGE_SIZE is optional. If defined, the client can omit the limit query parameter in requests. The pagination behavior can be further customized by overriding attributes in the LimitOffsetPagination class:
- default_limit: Numeric value specifying the default limit. Defaults to the PAGE_SIZE value.
- limit_query_param: Name of the query parameter used for the limit. Defaults to 'limit'.
- offset_query_param: Name of the query parameter used for the offset. Defaults to 'offset'.
- max_limit: Maximum allowable limit that the client can request. Defaults to None.
- template: Template name used to render pagination controls in the browsable API.
Fetching Paginated Results:
To retrieve paginated results using limit-offset pagination, the HTTPie command is:
http :8000/robot/
Output:
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 541
Content-Type: application/json
Date: Mon, 01 Feb 2021 06:47:42 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": "http://localhost:8000/robot/?limit=2&offset=2",
"previous": null,
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2019-10-12T00:00:00Z",
"name": "FANUC M-710ic/50",
"price": 37000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/1/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-05-10T00:00:00Z",
"name": "IRB 910SC",
"price": 27000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/2/"
}
]
}
Fetching the Next Set of Results:
Based on the next field from the previous response, the following HTTPie command retrieves the next set of results:
http GET ":8000/robot/?limit=2&offset=2"
Output:

Fetching Results with Custom Limit and Offset:
To retrieve a specific number of items starting from a defined position, the following HTTPie command can be used:
http GET ":8000/robot/?limit=1&offset=0"
Output:

The CursorPagination style provides a cursor-based indicator to navigate through the result set. It allows only forward or backward movement and does not permit navigation to arbitrary positions. It requires a timestamp or ordering field on the model instance, and results are ordered by -created by default.
To enable this pagination style globally, set rest_framework.pagination.CursorPagination as the DEFAULT_PAGINATION_CLASS in settings.py:
Python
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 2,
}
The behavior of CursorPagination can be modified by overriding its class attributes. Key attributes include:
- page_size: Number of items per page (numeric value). Defaults to the PAGE_SIZE setting.
- cursor_query_param: Name of the query parameter used for the cursor. Defaults to 'cursor'.
- ordering: Field or list of fields used to order the results. Defaults to -created. Can also be overridden using OrderingFilter on the view.
- template: Template name for rendering pagination controls in the browsable API.
To customize the ordering, a new file named custompagination.py can be created in the app folder (e.g., robots) with the following code:
Python
from rest_framework.pagination import CursorPagination
class CursorPaginationWithOrdering(CursorPagination):
# order based on id
ordering = 'id'
The custom CursorPaginationWithOrdering class can be configured as the default pagination class in settings.py by updating the REST_FRAMEWORK settings:
Python
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'robots.custompagination.CursorPaginationWithOrdering',
'PAGE_SIZE': 2,
}
To fetch the first page of results using the custom cursor-based pagination, the HTTPie command is:
http :8000/robot/
Output:

To retrieve the next set of results, use the cursor value provided in the previous response. The HTTPie command is:
http :8000/robot/?cursor=cD0y
Output:
Explore
Python Fundamentals
Python Data Structures
Advanced Python
Data Science with Python
Web Development with Python
Python Practice