【问题标题】:Django Rest Framework add page number attribute using the PageNumberPagination classDjango Rest Framework 使用 PageNumberPagination 类添加页码属性
【发布时间】:2018-03-19 12:21:17
【问题描述】:

我正在使用 Django 和 Django rest 框架构建一个 API,并且我正在尝试在 json 结果中添加页码。我正在尝试在返回的结果中添加页码,例如,我目前正在获取此信息;

{
  "links": {
    "next": null,
    "previous": null
  },
  "count": 1,
  "results": [
    {
      "url": "http://127.0.0.1:8000/api/brands/1/?format=json",
      "name": "microsoft",
      "description": "Nothing",
      "top_brand": true,
      "guid": "microsoft"
    }
  ]
}

但我想得到这样的东西;

{
  "count": 1,
  "results": [
    {
      "url": "http://127.0.0.1:8000/api/brands/1/?format=json",
      "name": "microsoft",
      "description": "Nothing",
      "top_brand": true,
      "guid": "microsoft"
    },
    ...
  ],
  "page_number": 1,
  "from": 1,
  "to": 10,
  "last_page": 4
}

最重要的属性是 page_number,但我不太确定如何使用 self... 从父类中获取它,除了使用函数之外,我看不到直接的方法。这是我的代码;

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

    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,
            'page_number': self.page.paginator...,
        })

【问题讨论】:

    标签: python json django django-rest-framework


    【解决方案1】:

    您可以在视图集中使用自定义分页并在自定义视图上进行更改

    pagination.py

    class CustomPageNumber(pagination.PageNumberPagination):
        page_size = 2
    
        def get_paginated_response(self, data):
            return Response(OrderedDict([
                 ('lastPage', self.page.paginator.count),
                 ('countItemsOnPage', self.page_size),
                 ('current', self.page.number),
                 ('next', self.get_next_link()),
                 ('previous', self.get_previous_link()),
                 ('results', data)
             ]))
    

    在你看来

    class TestViewSet(viewsets.ReadOnlyModelViewSet):
        queryset = Test.objects.all().order_by('-created_at')
        serializer_class = TestSerializer
    
        @list_route(methods=['get'], url_path='get-records/(?P<pk>[^/]+)')
        def get_record(self, request, pk):
            self.pagination_class = CustomPageNumber
            queryset = self.filter_queryset(self.queryset.filter(course=pk))
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data) 
    

    你需要在你的 settings.py 中配置

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

    如果您想了解更多信息,请参阅文档custom-pagination-class

    【讨论】:

    • 这里 def get_paginated_response 的响应中有一个错误...响应“ last_page : self.page.paginator.count ”没有给出总页数...它会给你总记录,这将获取。
    • 最好改用("countItemsOnPage", self.get_page_size(self.request))。如果查询包含像 &amp;page_size=5 这样的 page_size 参数,则应反映在响应中,而不是始终反映在 2
    • 我偶然发现了这个,试图在我的分页中获取当前页面和最后一页。这确实有效,但只有一个小问题。最后一页实际上并没有得到最后一页。为了做到这一点,我刚刚做了 last_page = math.ceil(self.page.paginator.count / self.page_size) 然后在 Response ('last_page', last_page), 。希望这对某人有所帮助。
    【解决方案2】:

    如果我理解你是正确的,你可以使用self.page.number

        return Response({
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'results': data,
            'page_number': self.page.number,
            #              ^^^^^^^^^^^^^^^^
        })
    

    【讨论】:

      【解决方案3】:

      我相信像这样获得tofrom 可能更适用:

      class MyCustomPagination(pagination.PageNumberPagination):
      
          def get_from(self):
              return int((self.page.paginator.per_page * self.page.number) - self.page.paginator.per_page + 1)
      
          def get_to(self):
              return self.get_from() + int(len(self.page.object_list)) - 1
      
          def get_paginated_response(self, data):
      
              return Response({
                  'next': self.get_next_link(),
                  'previous': self.get_previous_link(),
                  'count': self.page.paginator.count,
                  'total_pages': self.page.paginator.num_pages,
                  'page_number': self.page.number,
                  'per_page': self.page.paginator.per_page,
                  'from': self.get_from(),
                  'to': self.get_to(),
                  'results': data
              })
      

      【讨论】:

        【解决方案4】:

        自从回答了这个问题后,就有一个新组件采用 :number-of-pages 属性。

        https://bootstrap-vue.org/docs/components/pagination-nav

        【讨论】:

          【解决方案5】:

          在您的回复中显示当前页码 基本上你可以在你的views.py文件上做到这一点 通过创建一个自定义的“pagination_class”,如下所示。

          我有模型调用“评论”, 注意:这只是示例,请根据您的要求进行更改:

          ## view all comments with Custom paganation ##
          class MyCustomPagination(PageNumberPagination):
              page_size = 1
              page_size_query_param = 'page_size'
              def get_paginated_response(self, data):
                  return Response({
                      'count': self.page.paginator.count,
                      'page_number': self.page.number,
                      'next': self.get_next_link(),
                      'previous': self.get_previous_link(),
                      'results': data,
                  })
          
          
          
          
          class C_ApiCommentListView(ListAPIView):
              queryset = Comment.objects.all()
              serializer_class = App1CommentSerializer
              authentication_classes = (TokenAuthentication,)
              permission_classes = (IsAuthenticated,)
              pagination_class = MyCustomPagination
              filter_backends = (SearchFilter, OrderingFilter)
              search_fields = ('COM_comment', 'COM_title', 'COM_user__username')
          

          我希望这对你有帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-11-06
            • 2020-08-21
            • 1970-01-01
            • 1970-01-01
            • 2022-01-14
            • 1970-01-01
            • 2016-07-03
            • 2015-10-15
            相关资源
            最近更新 更多