Реализация пагинации с Django REST Framework в Python
В этом уроке вы узнаете, как использовать функцию пагинации в Django REST Framework Pagination для разделения списка записей на несколько страниц в Python.
- Что такое пагинация Django REST Framework
- Стили пагинации Django
- Нумерация страниц
- Лимит смещения пагинации
- Курсорная пагинация
Что такое пагинация 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" } ] }