Django使用Paginator插件实现分页查询

一、分页插件Paginator

      在做分页时,需要在url后需要拼接参数:  ?page=0&size=10

      需要导入Paginator 插件类

from django.core.paginator import Paginator

      第一步,获取到page和size,注意page需要从1开始,否则会报错,另外可以指定默认的page=1,size=10:
     

 page = request.GET.get('page', '1')  # 默认跳转到第一页
 size = request.GET.get('size', '10')

  第二步,获取到QuerySet结果集:

notes = Note.objects.all().filter(student_id=uid, delete_datetime=None)

   第三步,创建Paginator对象,传入结果集和分页的大小:

 page_obj = Paginator(notes, size)

   第四步,根据页数来获取最终的结果集,可以直接使用object_list来获取到结果:

page_data = page_obj.get_page(page)
res = page_data.object_list
print("res",res)

     打印结果:

<TimestampQuerySet [<Note: 第一节课,第一条笔记>, <Note: 第一节课,第二条笔记>, <Note: >, <Note: >, <Note: >, <Note: >, <Note: >, <Note: >]>

 

二、分页的坑

坑一:

         如果分页的页数大于总页数,该分页插件会取到最大的那个页数进行展示! 

如下, 查询出的结果中总共有2页,每页5条,我在传分页的时候使用page=3 & size= 5 时,会出现django框架会自动选择第二页的情况!

但是我明明传的page是3 !!!!! 

 

解决方法:

如果传入的page>  total_page,那么就返回[] , page 是字符串的话需要先转换为int类型。

  page_obj = Paginator(invoice_heads, size)
            page_data = page_obj.get_page(page)
            total_page = page_obj.num_pages
            if page > total_page:
                r.data = []
            else:
                res = page_data.object_list
                data = []
                for i in res:
                    d = InvoiceHeadSerializers(i).data
                    line = InvoiceLine.objects.filter(head=i).values('goods_name').annotate(
                        max_amount=Max("amount")).first()
                    if line is not None and "main_goods_name" not in d:
                        d["main_goods_name"] = line["goods_name"]
                    else:
                        d["main_goods_name"] = ""
                    d["rate_amount"] = i.total_amount - i.amount
                    data.append(d)
                r.data = data

 

坑二: 

       如果对查询出来的queryset不排序,使用Paginator做分页时,会出现警告:

       UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list

       解决方法一,在代码后面拼接.order_by("id")方法

records = VATTaxReportRecords.objects.filter(
                ~Q(certificate_serial_number=None),
                status="S",
                resource_uid=resource_uid,
                user_id=user_id,
            ).order_by("id")

 

     方法二,在model里的Meta里添加属性ordering

   class Meta:
        verbose_name_plural = "报表记录"
        verbose_name = "报表记录"
        db_table = "tax_report_records"
        ordering = [‘id’]

 

 

 

 


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦钢铁侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值