Django进阶–分页
本文是一篇学习笔记,在官方文档基础上加以整理而形成。想要查看关键字段官方文档,请点击相应的符号:¶
1. 简介
关于分页查询我是一个新手,简谈我对手动编写分页查询的感受:首先是对新手的不友好、第一次写一个简单的分页花了一天的时间;其次就是分页归属于查询,所以和查询的逻辑、身份验证以及数据库的操作密不可分,在一个大知识环境里编写代码还是比较容易出错的;还有就是日后修改业务时,阅读代码的艰辛。
因为本人纯属菜鸟,虽然以上问题对于高手可以随手为之,但我走的却是很艰辛。所以决定学习Django
官方封装的分页功能pagination
,他不能简化逻辑,只是能降低代码量(封装了一些底层方法)。
django版本:2.1.7
数据库:mysql,通过模型建立关系。
2 Pagiantor ¶
2.1 简介
Paginator
类是 Django 官方提供的分页管理器。
#实例化
pagi = (object_list, per_page)
- object_list:任何可迭代对象,list, tuple, str和模型查询返回的QuerySet;
- per_page:一页几个元素,指定页面大小。
举个栗子
In [1]: from book.models import Student
In [1]: from django.core.paginator import Paginator
In [18]: stus = Student.objects.all().order_by('-c_time') #用QuerySet对象建立分页管理器,必须先排序
In [21]: stus
Out[21]: <QuerySet [
<Student: id<1>name[新一]gender(男)age|16|c_time:2019-03-20 15:25:09+00:00>,
<Student: id<2>name[元太]gender(男)age|16|c_time:2019-03-20 15:26:16+00:00>,
<Student: id<23>name[阿飞]gender(男)age|25|c_time:2019-03-26 00:55:50.108942+00:00>
]>
In [22]: pagi = Paginator(stus, 3)
- 关于模型的相关知识,可以查阅我的:Django模型–数据库(MySQL)-初识
- pagi 就是一个分页管理器对象我们可以通过它,实现分页。
- object_list对象必须有 count 或者 _len_ 方法
2.2 属性 ¶
1. count
¶
返回object_list
的长度,即所有元素的总个数。
# pagi是上个例子中,Student表中所有数据的分页管理器
In [29]: pagi.count #返回总的记录条数
Out[29]: 11
In [30]: Student.objects.all().only().count() #Student表中确实有11条数据
Out[30]: 11
- count 属性被调用时,Paginator会先调用object_list.count(),若无该方法、回退使用
len(object_list)
。 - 对于数据库对象,count方法效率极高(和数据库引擎有关);
2. num_pages ¶
返回总共有多少页
In [31]: pagi.num_pages
Out[31]: 4
# pagi.count = 11; per_page = 3; 11 / 3 向上取整得4
3. page_range
¶
返回下标从1开始的页码迭代器,每个元素是页码对应的整数;比如一个分页器将object_list分为三页、则返回: [1, 2, 3]
In [32]: pagi.page_range
Out[32]: range(1, 5)
# pagi.num_pages = 4。
3 Page对象 ¶
3.1 简介
每个Page
对象对应众多页面中的一个。
# Page对象通常不用手工创建
class Page (object_list, number, paginator)
# Page 依于 Paginator,所以通过 Paginator 创建
In [33]: pagi.page(1)
Out[33]: <Page 1 of 4>
# 一共有四个页面,这是第一个
3.2 方法 ¶
1. has_next
判断是否有下一页,若有、返回True;
In [36]: page1 = pagi.page(1) #page1 对应第一页
In [37]: page1.has_next()
Out[37]: True
2. has_previous
判断是否有上一页,若有、返回True;
In [39]: page1.has_previous()
Out[39]: False
3. has_other_pages
如果有下一页或上一页,返回True;
#创建一个仅包含1页的分页管理器对象。
In [44]: pagn = Paginator('abc', 3)
In [45]: pagen1 = pagn.page(1)
In [47]: pagn.num_pages
Out[47]: 1
In [49]: pagen1.has_other_pages()
Out[49]: False
4. next_page_number
返回下一页编号,如果下一页不存在触发异常InvalidPage
(后面会讲到,即页面参数异常,源于页面参数过界)
In [50]: page1.next_page_number()
Out[50]: 2
5. previous_page_number
返回上一页编号,如果上一页不存在触发异常InvalidPage
In [52]: page2 = pagi.page(2)
In [53]: page2.previous_page_number()
Out[53]: 1
6. start_index
返回本页第一个元素在objects_lis
t中的编号,注意:编号会从1开始。
# pagi 共有11条记录(元素),每页3条记录,共4页
# page1是第一页,函数返回编号1
In [55]: page1.start_index()
Out[55]: 1
# page2是第二页,函数返回编号4(1 * 3 +1 = 4)
In [56]: page2.start_index()
Out[56]: 4
6. end_index
返回本页最后一个元素在objects_lis
t中的编号,注意:编号会从1开始。
In [58]: page1.end_index() #1 * 3
Out[58]: 3
In [59]: page2.end_index() #2 * 3
Out[59]: 6
3.2 属性
1. object_list
返回对象列表objects_list
In [60]: pagen1.object_list
Out[60]: 'abc'
2. number
返回当前页面编号
In [65]: page1.number
Out[65]: 1
In [66]: page2.number
Out[66]: 2
3. paginator
返回当前页面所属的分页管理器Paginator
对象实例
In [67]: page2.paginator
Out[67]: <django.core.paginator.Paginator at 0x7f6a63f33438>
In [68]: page2.paginator.num_pages
Out[68]: 4
感谢潭州,一路走来,始终如一;
心蓝老师是最棒的;