DRF post请求实现分页

这篇博客介绍了如何在Django Rest Framework(DRF)中,通过POST请求实现查询和分页。首先,定义了一个自定义分页类`MyPageNumberPagination`,设置查询参数和分页大小。然后,在`ItemList`视图中,从POST数据中获取分页参数并添加到query_params中,使DRF能够处理POST请求的分页。此外,还提供了一个自定义的分页响应格式,包括内容、是否为最后一页、上一页、最大条数、总条数和总页数等信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 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来调用自定义的分页返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值