【问题标题】:Django Rest Framework Pagination Settings - Content-RangeDjango Rest 框架分页设置 - 内容范围
【发布时间】:2015-09-03 02:23:58
【问题描述】:

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

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

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

【问题讨论】:

    标签: django pagination django-rest-framework


    【解决方案1】:

    1.在响应中包含Link Header:

    要在响应中包含Link 标头,您需要创建一个自定义分页序列化器类,它应该是pagination.BasePagination 的子类并覆盖get_paginated_response(self, data) 方法。

    示例(取自docs):

    假设我们想用修改后的格式替换默认的分页输出样式,该格式在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 Header:

    您也可以发送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
    

    【讨论】:

    • 如果你想让它给出内容范围而不是链接怎么办。 Dojo 请求一个范围,而不是一个链接。不过这很有帮助!
    • 你也可以这样做。只需创建 Content-Range 标头并将其传递给响应。我已经更新了答案。
    • 对不起 - 这部分对我来说很新。您是否有任何资源或示例说明有人在哪里这样做,以便我可以看到它,看看它是什么样子?我真的很感谢你的回答!如果总价值总是在变化怎么办?
    • 我添加了一个例子。希望能帮助到你! :)
    • 谢谢@Rahul Gupta ...过去 3 天一直有这个问题
    【解决方案2】:

    DRF 在其documentation: django-rest-framework-link-header-pagination 中推荐第三方包

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

    这里是取自 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"
    

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

    【讨论】:

      猜你喜欢
      • 2017-10-26
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      相关资源
      最近更新 更多