Реализация пагинации с Django REST Framework в Python

В этом уроке вы узнаете, как использовать функцию пагинации в 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"
        }
    ]
}
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *