一.基于PageNumberPagination實現(xiàn)分頁
Rest Framework分頁參考地下:https://www.django-rest-framework.org/api-guide/pagination/#pagenumberpagination
1.自定義分頁,需要實現(xiàn)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分頁還有其他方式 ,詳情可參考上官網(wǎng)地址:
