В этом уроке вы узнаете, как использовать функцию пагинации в Django REST Framework Pagination для разделения списка записей на несколько страниц в Python.
Что такое пагинация Django REST Framework
Предположим, у вас есть тысячи записей, и вы хотите показать их пользователям. Но экран довольно ограничен. Поэтому вам часто приходится разбивать эти записи на страницы, каждая из которых содержит 5 или 10 записей.
Функция разбиения на страницы позволяет эффективнее использовать ресурсы сервера, сократить время загрузки и улучшить взаимодействие с пользователем.
Пагинация Django REST Framework позволяет разбить большой набор результатов на отдельные страницы с помощью нескольких простых настроек.
Продолжим проект Todo API из предыдущего урока. Давайте добавим несколько todo в проект, чтобы протестировать пагинацию:

Стили пагинации Django
Django предоставляет различные стили для разбиения данных на страницы. Давайте рассмотрим их.
Нумерация страниц
Стиль пагинации номера страницы принимает один номер страницы в параметрах запроса. Вы можете легко переходить к определенным страницам.
Чтобы настроить пагинацию номеров страниц, добавьте ее в REST_FRAMEWORK в settings.py проекта.
Например, следующий код указывает DRF использовать стиль PageNumberPagination с размером страницы 2:
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
После завершения настройки вы можете сделать запрос GET к конечной точке /api/v1/todos?page=2 в веб-браузере.
Вот ответ:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 6,
"next": "http://localhost:8000/api/v1/todos/?page=3",
"previous": "http://localhost:8000/api/v1/todos/",
"results": [
{
"id": 3,
"title": "Master Django REST API",
"completed": false,
"user": "john"
},
{
"id": 6,
"title": "Deploy API to Server",
"completed": false,
"user": "john"
}
]
}
В ответе:
- count указывает общее количество записей.
- «next» и «previous» обозначают ссылки на следующую и предыдущую страницу.
- results сохраняют записи, указанные PAGE_SIZE. В этом примере каждая страница содержит 2 записи.
Лимит смещения пагинации
Пагинация с ограничением смещения имитирует способ поиска нескольких записей в базе данных. Клиент сообщает серверу две вещи:
- Максимальное количество записей, возвращаемых на страницу (лимит).
- Где среди записей начинается список (смещение).
Если вы знакомы с MySQL или PostgreSQL, то пагинация с ограничением смещения работает так же, как предложения LIMIT и OFFSET.
Ниже показано, как настроить ограничение смещения пагинации в settings.py проекта:
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2
}
Если вы сделаете запрос GET к конечной точке /api/v1/todos/?limit=2&offset=2, вы получите следующий ответ:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 6,
"next": "http://localhost:8000/api/v1/todos/?limit=2&offset=4",
"previous": "http://localhost:8000/api/v1/todos/?limit=2",
"results": [
{
"id": 3,
"title": "Master Django REST API",
"completed": false,
"user": "john"
},
{
"id": 6,
"title": "Deploy API to Server",
"completed": false,
"user": "john"
}
]
}
Стиль LimitOffsetPagination работает так же, как стиль PageNumberPagination, за исключением того, что он использует два параметра строки запроса: limit и offset.
Курсорная пагинация
Ограничением методов на основе смещения, включая PageNumberPagination и LimitOffsetPagination, является то, что они неэффективны для очень больших наборов данных.
Вот тут-то и приходит на помощь cursor pagination. Курсорная пагинация эффективно работает для больших наборов данных и использует непрозрачный индикатор «курсора» для листания. Он предлагает элементы управления вперед и назад для навигации.
Курсорная пагинация требует последовательного и уникального порядка в наборе результатов. Она также не позволяет переходить на произвольную позицию в наборе данных.
Ниже показаны настройки CursorPagination в файле settings.py:
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 2
}
По умолчанию CursorPagination предполагает, что модель имеет поле временной метки «created». Сначала будут возвращены самые последние созданные записи, поскольку порядок по умолчанию — «-created».
Если модель не имеет поля «создано», вам необходимо указать другое поле, например id. Для этого выполните следующие действия:
Сначала определите подкласс класса CursorPagination:
class TodoCursorPagination(CursorPagination):
ordering = 'id' # Default ordering
page_size = 2 # Set your desired page size
Во-вторых, используйте TodoCursorPagination в представлении:
class TodoList(generics.ListCreateAPIView):
pagination_class = TodoCursorPagination
# ...
В этом примере показано, как настроить стиль пагинации на уровне представления. В отличие от глобальной настройки, настройка на уровне представления применяется только к определенному представлению.
Если вы сделаете запрос GET к конечной точке API /api/v1/todos/, вы получите следующий ответ:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"next": "http://localhost:8000/api/v1/todos/?cursor=cD0y",
"previous": null,
"results": [
{
"id": 1,
"title": "Learn Python",
"completed": false,
"user": "john"
},
{
"id": 2,
"title": "Study Django",
"completed": false,
"user": "john"
}
]
} 