Django Rest Framework 分页设置 - Content-Range

Django Rest Framework Pagination Settings - Content-Range

6.30.15 - 我怎样才能使这个问题更好,对其他人更有帮助?反馈会很有帮助。谢谢!

我正在使用 DRF 作为 Dojo/Dgrid 网络应用程序的服务器端。 Dojo 需要来自服务器的 content-range 或范围响应。目前它不发送任何内容,因此 dgrid.grid 的分页无法正常工作。

在 DRF 文档中指出“响应 headers 中包含的分页链接,例如 Content-Range 或 Link。”但是没有给出关于如何设置 DRF API 来执行此操作的明确过程。我对网络应用程序开发还比较陌生。如有任何帮助,我们将不胜感激!

1.在响应中包括 Link Header:

要在您的响应中包含 Link header,您需要创建一个自定义分页序列化程序 class,这应该是 class pagination.BasePagination 和覆盖 get_paginated_response(self, data) 方法。

示例(取自docs):

假设我们想用修改后的格式替换默认的分页输出样式,其中包括 Link header 中的下一个和上一个链接,我们覆盖 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)

在此之后,我们需要在我们的设置中包含此分页 class,以便 DRF 使用它而不是默认分页 classes。

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

API 列表端点的响应现在将包含 Link header.

2。在响应中包括 Content-Range Header:

您也可以发送 Content-Range header 而不是 Link。只需创建一个 headers 字典,其中 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)

假设这是 header 收到的:

Content-Range: items 0-9/50 

这告诉我们响应有一个 Content-Range header,值为 items 0-9/50。这表示前 10 项已返回总数 50

你也可以用*代替总数。如果计算总数很昂贵。

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

DRF 在其 documentation: django-rest-framework-link-header-pagination

中推荐第三方包

它应该遵循与 Github API 相同的路径,这基本上是执行其他答案建议的正确方法。

这里是 Link header 取自 Github 的 API 指南的示例:

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"

我还没有尝试过这个包,但我会在完成后报告。