DRF的查询条件是在query_params中,默认是GET方法的。如果想要用POST请求去做查询和分页。就需要往query_params添加对应的分页参数。
from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 10
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 100
class ItemList(generics.GenericAPIView):
queryset = ItemModel.objects.all().order_by('-createdTime')
serializer_class = ItemSerializer
pagination_class = MyPageNumberPagination
def post(self, request):
try:
page = request.data.get("page")
size = request.data.get("size")
if page: # 判断请求中是否有page和size参数
request.query_params._mutable = True # 让查询参数dict变为可编辑
# query_params该参数会返回请求的查询参数,是个dict _mutable属性表示是否可编辑,默认是False
request.query_params['page'] = page # 添加page查询参数
if size:
request.query_params['size'] = size # 添加size查询参数
request.query_params._mutable = False # 让查询参数dict变为不可编辑
item_queryset = self.get_queryset()
item_page = self.paginate_queryset(item_queryset)
if item_page:
item_serializer = self.get_serializer(item_page, many=True)
return JsonResponse(data=item_serializer.data, code=0, status=status.HTTP_200_OK)
serializer = self.get_serializer(item_queryset, many=True)
return JsonResponse(code=0, data=serializer.data, status=status.HTTP_200_OK)
except (ParseError, NotFound) as e:
return JsonResponse(code=1, msg=str(e), status=status.HTTP_400_BAD_REQUEST)
通过往query_params这个查询参数里面添加参数来实现post请求分页。
自定义分页返回格式
import math
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 10
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 100
def get_paginated_response(self, data):
last = False # 是否最后一页:默认False
previous_page = 1 # 当前页数的上一页
max_size = self.page_size # 每页最大记录数
count = self.page.paginator.count # 总条数
page = self.page.number # 请求的页数
max_page_size = self.max_page_size # 上面page_size_query_param参数对应设置的页面条数最大值
# 是否有下一页
if self.page.has_next() is False: # 是否有下一页返回False
last = True
# 上一页数
if page - previous_page > 1:
previous_page = page - 1
# 查询时可用最大条数
# 在请求的查询参数dict中,将page_size_query_param的值作用key来查询
query_size = self.request.query_params.get(self.page_size_query_param) # 获取请求参数中条数的值
if query_size:
if not isinstance(query_size, int):
try:
query_size = int(query_size)
except ValueError:
return ErrorResponse(msg="%s:应该是int类型" % self.page_size_query_param)
if query_size: # 当有请求中有page_size_query_param设置的值时,最大条数是根据请求中的值。比如{"size":20},这时每页最大参数应该是20
max_size = query_size
if max_page_size: # 如果存在max_page_size设置
max_size = max_page_size # 将最大条数设置为max_page_size的值
# 总页数
if query_size:
total_pages = math.ceil(count / query_size)
if query_size > max_page_size:
total_pages = math.ceil(count / max_page_size)
else:
total_pages = math.ceil(count / max_size)
ret_data = dict() # 创建返回内容的dict
ret_data['content'] = data # 将数据通过content字段返回
ret_data['last'] = last # last字段返回是否最后一页,false:不是 True:是
ret_data['previousPage'] = previous_page # previousPage返回上一页值
ret_data['maxSize'] = max_size # maxSize字段返回查询时可用最大条数
ret_data['totalElements'] = count # totalElements字段返回总条数
ret_data['totalPages'] = total_pages # totalPages字段返回总页数
return JsonResponse(code=0, data=ret_data, status=status.HTTP_200_OK)
if item_page:
item_serializer = self.get_serializer(item_page, many=True)
return self.get_paginated_response(item_serializer.data) # 使用get_paginated_response来调用自定义的分页返回