Руководство по API платформы Django REST (17): нумерация страниц

задняя часть Python API Django

Официальная оригинальная ссылка
Эта серия статей адрес github
Пожалуйста, укажите источник

нумерация страниц

Платформа REST включает поддержку настраиваемых стилей разбивки на страницы. Это позволяет разделить большие наборы результатов на отдельные страницы данных.

API пагинации поддерживает:

  • В виде разбитых на страницы ссылок как часть содержания ответа.
  • Включается в заголовок ответа как ссылка на страницу, напримерContent-RangeилиLink.

Встроенные стили в настоящее время представлены в виде ссылок с разбивкой на страницы как часть содержимого ответа. Этот стиль более доступен при использовании доступного для просмотра API.

Разбиение на страницы выполняется автоматически только при использовании общего представления или набора представлений. Если вы используете обычныйAPIView, вам нужно самостоятельно вызвать API разбиения на страницы, чтобы обеспечить возврат ответа с разбивкой на страницы. Например см.mixins.ListModelMixinиgenerics.GenericAPIViewИсходный код класса.

Это можно сделать, установив класс пагинации наNone, отключить пейджинг.

Установить стиль пагинации

Можно использовать стили пагинацииDEFAULT_PAGINATION_CLASSиPAGE_SIZEКлавиша настройки Глобальная настройка. Например, чтобы использовать встроенную разбивку по страницам с ограничением/смещением, вы можете сделать:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 100
}

Обратите внимание, что вам необходимо установить класс нумерации страниц и размер страницы, которые следует использовать. по умолчанию,DEFAULT_PAGINATION_CLASSиPAGE_SIZEобаNone.

вы также можете использоватьpagination_classСвойство задает класс разбиения на страницы для одного представления. Как правило, вы захотите использовать один и тот же стиль нумерации страниц во всем API, но вы можете изменить различные аспекты нумерации страниц, например размер страницы по умолчанию или максимальный размер, для каждого просмотра.

Изменить стиль пагинации

Если вы хотите изменить определенный аспект стиля нумерации страниц, вам необходимо наследовать от одного из классов нумерации страниц и установить свойства, которые вы хотите изменить.

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size'
    max_page_size = 10000

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 1000

Тогда вы можете использовать.pagination_classсвойство, чтобы применить новый стиль к представлению:

class BillingRecordsView(generics.ListAPIView):
    queryset = Billing.objects.all()
    serializer_class = BillingRecordsSerializer
    pagination_class = LargeResultsSetPagination

или использоватьDEFAULT_PAGINATION_CLASSКлавиша настройки применяет стили глобально. Например:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
}

Справочник по API

PageNumberPagination

Этот стиль разбивки на страницы принимает значение номера страницы в параметре запроса запроса.

Request:

GET https://api.example.org/accounts/?page=4

Response:

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}

Setup

Чтобы включить глобальноPageNumberPaginationстиль, пожалуйста, используйте следующую конфигурацию и установите по мере необходимостиPAGE_SIZE:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100
}

При использованииGenericAPIViewПодкласс , вы также можете установитьpagination_classсвойства для выбора на основе представленияPageNumberPagination.

Configuration

PageNumberPaginationКласс содержит некоторые свойства, которые можно переопределить, чтобы изменить стиль нумерации страниц.

Чтобы установить эти свойства, вы должны наследоватьPageNumberPaginationclass, затем включите свой собственный класс разбиения на страницы, как указано выше.

  • django_paginator_class- Класс Django Paginator для использования. По умолчаниюdjango.core.paginator.Paginator, что должно подойти для большинства случаев использования.
  • page_size- Числовое значение, указывающее размер страницы. Если установлено, оно будет переопределятьPAGE_SIZEпараметр. Значение по умолчанию такое же, какPAGE_SIZEКлюч настройки тот же.
  • page_query_param- Строковое значение, указывающее имя параметра запроса, используемого для управления пейджингом.
  • page_size_query_param- Строковое значение, указывающее имя параметра запроса, который позволяет клиенту устанавливать размер страницы для каждого запроса. По умолчаниюNone, что указывает на то, что клиент не может контролировать запрошенный размер страницы.
  • max_page_size- Числовое значение, представляющее максимально допустимый размер страницы. Это свойство доступно только вpage_size_query_paramТакже действует при установке.
  • last_page_strings- список или кортеж строк, определяющих возможныеpage_query_paramЗначение, используемое вместе для запроса последней страницы в коллекции. По умолчанию('last',)
  • template— Имя шаблона для использования при отображении элементов управления разбиением на страницы в доступном для просмотра API. Может быть переопределен для изменения стиля рендеринга или установлен наNoneчтобы полностью отключить управление разбивкой на страницы HTML. По умолчанию"rest_framework/pagination/numbers.html".

LimitOffsetPagination

Этот стиль разбиения на страницы отражает синтаксис, используемый при поиске нескольких записей в базе данных. Клиент содержит параметры запроса «limit» и «offset». limit указывает максимальное количество возвращаемых элементов и эквивалентен другим стилям.page_size. offset указывает начальную позицию запроса по отношению к полному набору несортированных элементов.

Request:

GET https://api.example.org/accounts/?limit=100&offset=400

Response:

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?limit=100&offset=500",
    "previous": "https://api.example.org/accounts/?limit=100&offset=300",
    "results": [
       …
    ]
}

Setup

Чтобы включить глобальноLimitOffsetPaginationstyle используйте следующую конфигурацию:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}

Кроме того, вы также можете установитьPAGE_SIZEключ. если используетсяPAGE_SIZEпараметр, тоlimitПараметры запроса будут необязательными и могут быть проигнорированы клиентом.

При использованииGenericAPIViewподкласс, вы также можете установитьpagination_classсвойства для выбора для каждого просмотраLimitOffsetPagination.

Configuration

LimitOffsetPaginationКласс содержит некоторые свойства, которые можно переопределить, чтобы изменить стиль нумерации страниц.

Чтобы установить эти свойства, вы должны наследоватьLimitOffsetPaginationclass, затем включите свой собственный класс разбиения на страницы, как указано выше.

  • default_limit- Числовое значение, указывающее предел, не указанный клиентом в параметре запроса. Значение по умолчанию такое же, какPAGE_SIZEКлюч настройки тот же.
  • limit_query_param- Строковое значение, указывающее имя параметра запроса "limit". По умолчанию'limit'.
  • offset_query_param- Строковое значение, указывающее имя параметра запроса "смещение". По умолчанию'offset'.
  • max_limit- Числовое значение, представляющее максимально допустимый лимит, который может запросить клиент. По умолчаниюNone.
  • template— Имя шаблона для использования при отображении элементов управления разбиением на страницы в доступном для просмотра API. Может быть переопределен для изменения стиля рендеринга или установлен наNoneчтобы полностью отключить управление разбивкой на страницы HTML. По умолчанию"rest_framework/pagination/numbers.html".

CursorPagination

Пейджинг на основе курсора предоставляет непрозрачный индикатор «курсор», который клиенты могут использовать для просмотра набора результатов. Этот стиль нумерации страниц обеспечивает только прямое и обратное управление и не позволяет клиенту перемещаться куда-либо.

Разбиение на страницы с помощью курсора требует существования уникального неизменного порядка элементов в результирующем наборе. Этот порядок обычно может быть отметкой времени создания в записях, так как это обеспечивает согласованность порядка.

Пейджинг на основе курсора сложнее, чем в других сценариях. Он также требует фиксированного порядка отображения наборов результатов и не позволяет клиентам произвольно индексировать наборы результатов. Но он дает следующие преимущества:

  • Обеспечивает последовательное представление с разбивкой на страницы. при правильном использованииCursorPaginationГарантирует, что клиенты не увидят один и тот же элемент при разбиении по страницам, даже если другие клиенты вставляют новые элементы во время разбиения по страницам.
  • Поддерживает использование очень больших наборов данных. Использование стилей разбиения на страницы на основе смещения может стать неэффективным или непригодным при разбиении по страницам с очень большими наборами данных. Схемы подкачки на основе курсора имеют свойства фиксированного времени и не замедляются при увеличении размера набора данных.

Детали и ограничения

Правильное использование пейджинга на основе курсора требует небольшого внимания к деталям. Вам нужно учитывать порядок, в котором вы хотите применить схему. По умолчанию нажать"-created"Сортировать. Это предполагает, что в экземпляре модели должно быть «созданное» поле метки времени, и визуализирует представление с разбивкой на страницы в стиле «временной шкалы», где самый последний добавленный элемент является первым.

Вы можете сделать это, переопределив класс пагинации на'ordering'атрибут илиOrderingFilterкласс фильтра сCursorPaginationИспользуется вместе для изменения порядка. иOrderingFilterПри совместном использовании следует рассмотреть возможность ограничения полей, по которым пользователь может выполнять сортировку.

Для правильного использования подкачки курсора поле сортировки должно удовлетворять следующим условиям:

  • Должно быть неизменяемым значением при создании, таким как метка времени, слаг или другое поле, которое устанавливается только один раз.
  • Должен быть уникальным или почти уникальным. Хорошим примером являются метки времени с миллисекундной точностью. Эта реализация подкачки курсора использует интеллектуальный стиль «позиция + смещение», который позволяет корректно поддерживать не строго уникальные значения в качестве сортировок.
  • Должно быть ненулевое значение, которое можно преобразовать в строку.
  • Не должно быть поплавка. Ошибки точности могут легко привести к неверным результатам. Совет: вместо этого используйте десятичные дроби. (Если у вас уже есть поле с плавающей запятой и вам нужно разбить его на страницы, вы можете найти его здесьПример использования десятичных знаков для ограничения точности. )
  • Поле должно иметь индекс базы данных.

Использование полей сортировки, которые не соответствуют этим ограничениям, как правило, по-прежнему будет работать, но вы потеряете некоторые преимущества разбиения курсора на страницы.

Setup

Чтобы включить глобальноCursorPaginationстиль, пожалуйста, используйте следующую конфигурацию, при необходимости изменитеPAGE_SIZE:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
    'PAGE_SIZE': 100
}

При использованииGenericAPIViewподкласс, вы также можете установитьpagination_classсвойства для выбора для каждого просмотраCursorPagination.

Configuration

CursorPaginationКласс содержит некоторые свойства, которые можно переопределить, чтобы изменить стиль нумерации страниц.

Чтобы установить эти свойства, вы должны наследоватьCursorPaginationclass, затем включите свой собственный класс разбиения на страницы, как указано выше.

  • page_size= Числовое значение, указывающее размер страницы. Если установлено, оно будет переопределятьPAGE_SIZEнастраивать. Значение по умолчанию такое же, какPAGE_SIZEКлюч настройки тот же.
  • cursor_query_param= строковое значение, указывающее имя параметра запроса "курсор". По умолчанию'cursor'.
  • ordering= Это должна быть строка или список строк, определяющих поля, к которым будет применяться разбиение на страницы с помощью курсора. Например:ordering = 'slug'. По умолчанию-created. Значение также можно использовать в представлении с помощьюOrderingFilterпокрывать.
  • template= Имя шаблона, используемого при отображении элементов управления разбиением на страницы в доступном для просмотра API. Может быть переопределен для изменения стиля рендеринга или установлен наNoneчтобы полностью отключить управление разбивкой на страницы HTML. По умолчанию"rest_framework/pagination/previous_and_next.html".

Пользовательский стиль пагинации

Чтобы создать собственный класс сериализации разбивки на страницы, вы должны наследоватьpagination.BasePaginationи перезаписатьpaginate_queryset(self, queryset, request, view=None)иget_paginated_response(self, data)метод:

  • paginate_querysetМетоду передается начальный набор запросов, и он должен возвращать итерацию, содержащую только данные с запрошенной страницы.
  • get_paginated_responseметод передает сериализованные данные страницы и возвращаетResponseпример.

Пожалуйста, обрати внимание,paginate_querysetметод может установить состояние экземпляра разбиения на страницы, а затемget_paginated_responseметод может использовать его.

взять каштан

Предположим, мы хотим заменить стиль вывода разбиения на страницы по умолчанию измененным форматом, который содержит вложенный ключ «ссылки» (содержащий ссылки на предыдущую страницу, следующую страницу). Мы можем указать собственный класс пагинации следующим образом:

class CustomPagination(pagination.PageNumberPagination):
    def get_paginated_response(self, data):
        return Response({
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'results': data
        })

Затем нам нужно установить пользовательский класс в конфигурации:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.CustomPagination',
    'PAGE_SIZE': 100
}

Обратите внимание, что если вам важно, как порядок ключей отображается в доступном для просмотра API, вы можете использовать его при построении тела ответа на разбивку на страницы.OrderedDict, что является необязательным.

Используйте свой собственный класс пагинации

Чтобы использовать свой пользовательский класс пагинации по умолчанию, используйтеDEFAULT_PAGINATION_CLASSпараметр:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination',
    'PAGE_SIZE': 100
}

Ответ API для конечной точки списка теперь будет содержатьLinkзаголовок вместо включения ссылки на страницу как часть тела ответа.

Разбиение на страницы и шаблоны

путем реализацииget_schema_fields()метод, вы также можете сделать элементы управления нумерацией страниц доступными для автоматической генерации схемы, предоставляемой инфраструктурой REST. Этот метод должен иметь следующую подпись:

get_schema_fields(self, view)

Метод должен возвращатьcoreapi.FieldСписок экземпляров.


Link Header

Пользовательский стиль пагинации с использованием заголовка «Ссылка»


Управление HTML-разбивкой на страницы

По умолчанию использование класса нумерации страниц приведет к отображению элемента управления нумерацией страниц HTML в доступном для просмотра API. Есть два встроенных стиля отображения.PageNumberPaginationиLimitOffsetPaginationКласс для отображения нумерованного списка страниц с элементами управления предыдущей и следующей страницы.CursorPaginationКласс отображает более простой стиль, который просто отображает элементы управления предыдущей и следующей страницы.

пользовательский контроль

Вы можете переопределить шаблон, который отображает элемент управления разбивкой на страницы HTML. Два встроенных стиля:

  • rest_framework/pagination/numbers.html
  • rest_framework/pagination/previous_and_next.html

Обслуживание шаблонов с этими путями в глобальном каталоге шаблонов переопределит отображение по умолчанию соответствующих классов разбиения на страницы.

В качестве альтернативы вы можете полностью отключить управление разбивкой на страницы HTML для подклассов существующего класса,template=NoneУстановить как свойство этого класса. Затем вам необходимо настроитьDEFAULT_PAGINATION_CLASSset key для использования вашего пользовательского класса в качестве стиля разбиения на страницы по умолчанию.

низкоуровневый API

Низкоуровневый API для определения того, должен ли класс разбивки на страницы отображать элементы управления в качестве экземпляра разбивки на страницы.display_page_controlsСвойства общедоступны. Если вам нужно отобразить элементы управления пейджингом в формате HTML, пользовательский класс пейджинга должен находиться вpaginate_querysetметод установлен наTrue.

.to_html()и.get_html_context()Методы также можно переопределить в пользовательских классах разбиения на страницы, чтобы дополнительно настроить способ отображения элемента управления.