Django Rest Framework 使用 PageNumberPagination 类添加页码属性
Posted
技术标签:
【中文标题】Django Rest Framework 使用 PageNumberPagination 类添加页码属性【英文标题】:Django Rest Framework add page number attribute using the PageNumberPagination class 【发布时间】: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...,
)
【问题讨论】:
【参考方案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))
。如果查询包含像 &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】:我相信像这样获得to
和from
可能更适用:
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')
我希望这对你有帮助。
【讨论】:
以上是关于Django Rest Framework 使用 PageNumberPagination 类添加页码属性的主要内容,如果未能解决你的问题,请参考以下文章
Django Rest Framework 和 django Rest Framework simplejwt 两因素身份验证
18-Django REST framework-使用Django开发REST 接口
如何在 django-rest-framework 中为 API 使用 TokenAuthentication
Django-rest-framework 和 django-rest-framework-jwt APIViews and validation Authorization headers