一.基于PageNumberPagination实现分页
Rest Framework分页参考地下:https://www.django-rest-framework.org/api-guide/pagination/#pagenumberpagination
1.自定义分页,需要实现PageNumberPagination
如下LargeResultsSetPagination,继承了PageNumberPagination
from collectionsimport OrderedDict
from django.core.paginatorimport Paginator, PageNotAnInteger, EmptyPage, InvalidPage
from rest_frameworkimport status
from rest_framework.exceptionsimport NotFound
from rest_framework.paginationimport PageNumberPagination, _positive_int
from rest_framework.responseimport Response
from common.utilsimport common_response
from common.utils.common_responseimport JsonResponse
# rest_framework分页
class LargeResultsSetPagination(PageNumberPagination):
page_size =10
page_size_query_param ='page_size'
max_page_size =10000
page_query_param ='page'
def get_paginated_response(self, data):
return common_response.Response_Success(data=OrderedDict([
('count', self.page.paginator.count),
('page', self.page.number),
('pages', self.page.paginator.num_pages),
('size', self.page.paginator.per_page),
('records', data),
]))
//重写了paginate_queryset,为了兼容get,post请求,传page,page_size或者不传这两个字段的分页
def paginate_queryset(self, queryset, request, view=None):
"""
Paginate a queryset if required, either returning a
page object, or `None` if pagination is not configured for this view.
"""
page_size =self.get_page_size(request)
if not page_size:
return None
paginator =self.django_paginator_class(queryset, page_size)
# 为了兼容post,get传或者不传page,重写了page_number的获取方法,将原方法下一行注释
# page_number = request.query_params.get(self.page_query_param, 1)
page_number =self.get_page(request)
if page_numberin self.last_page_strings:
page_number = paginator.num_pages
try:
self.page = paginator.page(page_number)
except InvalidPageas exc:
msg =self.invalid_page_message.format(
page_number=page_number, message=str(exc)
)
raise NotFound(msg)
if paginator.num_pages >1 and self.templateis not None:
# The browsable API should display pagination controls.
self.display_page_controls =True
self.request = request
return list(self.page)
# 重写pagination的get_page_size
def get_page_size(self, request):
if self.page_size_query_param:
if request.query_params.get(self.page_size_query_param):
sizes = request.query_params[self.page_size_query_param]
elif request.data.get(self.page_size_query_param):
sizes = request.data.get(self.page_size_query_param)
else:
return self.page_size
try:
return _positive_int(
sizes,
strict=True,
cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass
return self.page
# 定义获取page,默认返回第1页
def get_page(self, request):
if self.page_query_param:
if request.query_params.get(self.page_query_param):
sizes = request.query_params[self.page_query_param]
elif request.data.get(self.page_query_param):
sizes = request.data.get(self.page_query_param)
else:
return 1
try:
return _positive_int(
sizes,
strict=True,
cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass
return 1
2.需要配置使用自定义的分页
在项目settings.py文件 REST_FRAMEWORK配置下增加
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 100}
效果如下:
Rest framework分页还有其他方式 ,详情可参考上官网地址: