Настройки пагинации 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"
Я еще не попробовал пакет, но сообщу, когда сделаю.