Настройки пагинации Django Rest Framework - Content-Range

6.30.15 - Как я могу сделать этот вопрос лучше и более полезным для других? ОБРАТНАЯ СВЯЗЬ БУДЕТ ПОЛЕЗНОЙ. СПАСИБО!

Я использую DRF в качестве серверной стороны для веб-приложения Dojo / Dgrid. Dojo нужен ответ диапазона содержимого или диапазона с сервера. В настоящее время он не отправляет и поэтому нумерация страниц для dgrid.grid не работает должным образом.

В документации DRF говорится: "Пагинационные ссылки, которые включены в заголовки ответа, такие как Content-Range или Link". Но не дает четкого процесса, КАК настроить DRF API для этого. Я все еще относительно новичок в разработке веб-приложений. Любая помощь будет оценена!

1 ответ

Решение

1. Включая Link Заголовок в ответе:

Чтобы включить Link заголовок в вашем ответе, вам нужно создать пользовательский класс сериализатора пагинации, это должно быть подклассом pagination.BasePagination и переопределить get_paginated_response(self, data) метод.

Пример (взят из документов):

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

class LinkHeaderPagination(pagination.PageNumberPagination):

    def get_paginated_response(self, data):
        next_url = self.get_next_link()
        previous_url = self.get_previous_link()

        if next_url is not None and previous_url is not None:
            link = '<{next_url}; rel="next">, <{previous_url}; rel="prev">'
        elif next_url is not None:
            link = '<{next_url}; rel="next">'
        elif previous_url is not None:
            link = '<{previous_url}; rel="prev">'
        else:
            link = ''

        link = link.format(next_url=next_url, previous_url=previous_url)
        headers = {'Link': link} if link else {}

        return Response(data, headers=headers)

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

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

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

вол

2. Включая Content-Range Заголовок в ответе:

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

Например:

class ContentRangeHeaderPagination(pagination.PageNumberPagination):

    def get_paginated_response(self, data):
        total_items = self.page.paginator.count
        item_starting_index = self.page.start_index() - 1 # In a page, indexing starts from 1
        item_ending_index = self.page.end_index() - 1

        content_range = 'items {0}-{1}/{2}'.format(item_starting_index, item_ending_index, total_items)      

        headers = {'Content-Range': content_range} 

        return Response(data, headers=headers)

Предположим, это заголовок получен:

Content-Range: items 0-9/50 

Это говорит нам о том, что ответ имеет Content-Range заголовок со значением как items 0-9/50, Это указывает на то, что первые 10 товаров возвращены из общего количества. 50,

Вы также можете использовать * вместо общего нет. из пунктов, если подсчет итогов стоит дорого.

Content-Range: items 0-9/* # Use this if total is expensive to calculate

DRF рекомендует сторонний пакет в своей документации: https://github.com/tbeadle/django-rest-framework-link-header-pagination

Предполагается, что он следует тем же путем, что и Github API, что в принципе является правильным способом выполнения того, что предлагает другой ответ.

Вот пример заголовка Link, взятого из руководства API Github:

Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next",
  <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last",
  <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first",
  <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev"

Я еще не попробовал пакет, но сообщу, когда сделаю.

Другие вопросы по тегам