目录
1 概念
分页就是把很多的内容分成多页让用户选择预览,比如说百度的这里就是分页功能
有两个优点
- 方便阅读
- 减少数据提取量,减轻服务器压力
在django中可以使用django.core.paginator来方便的使用分页功能
2 简单使用
页码可以直接放在路由里面(比如 /test_page/4 ,这种就是第四页),也可以放在查询字符串作为参数传递(比如 /test_page?page=4)
一般会使用查询字符串的形式,少一些路由会方便一些
2.1 代码
首先我们先搞一个视图
首先导入django.core.paginator中的Paginator,之后进入视图,视图中的代码的意思依次是
- 使用get拿到当前页数,如果没有当前页数,默认为1
- 定义所有被分页的数据,只要是一个列表就行
- 初始化分页对象,第一个参数是所有数据,第二个参数是一页显示多少个数据(给2就是一页显示两个数据)
- 获取当前的page对象
- 上面的流程中提到了两个对象,一个是分页器对象,另一个page对象,下面会具体讲一下
再搞一个路由
最后编写test_page.html
用了很多的方法与属性,我们先看效果,后面再讲
2.2 效果
打开后是这样的
点击下一页
再点击下一页
点击上一页
点击链接1
发现符合我们使用的基本要求
3 分页器对象
分页器对象负责分页数据整体的管理,使用django.core.paginator中的构造函数Paginator实例化对象,Paginator有两个阐述,第一个参数是所有要分页的数据,第二个参数是每页显示多少个数据
有四个常用属性
- count 需要分页数据的对象总数 (例子中all_data的长度)
- num_pages 分页后的页面总数(总共分出来多少页)
- page_range 从1开始的页码范围。如果你分出来3页,page_range的内容就是[1,2,3]。如果你分出来4页,pange_range的内容就是[1,2,3,4]
- per_page 每页数据的个数,这个是你创建paginator对象的第二个参数,与你每页实际有多少个数据无关。比如例子中最后一页是一组数据,但调用这个属性依然会返回2
我们在模板层中使用到了page_range属性,用page_range做出了页数索引
4 page对象
page对象是描述当前页信息的对象
4.1 创建对象
使用paginator对象的page()方法创建,参数为执行的页码索引(从1开始)
- 如果提供的页码不存在,会抛出InvalidPage异常。
4.2 常见异常
InvalidPage异常是一个大类,包含下面两个异常子类
当传入不是一个整数值的时候,会出现PageNotAnInteger异常,这个异常基本不会出现,因为我们获取当前页信息的时候都会int()一下,取而代之是这种错误
- int()目前不能将字符串型的浮点数转换为整型
如果拿到的页数是无效值,比如你只分了三页,你给非[1,2,3]的值,就会抛出EmptyPage的错误
4.3 常见属性
- object_list 当前页上所有数据对象的列表,在例子中,比如你的当前页是第一页,那么你的object_list就是[a,b]
- number 当前页的序号(从1开始),比如你当前是第一页,那么number就是1
- paginator 当前页的分页器对象,我们可以用这个属性进行切换分页器对象与当前页对象
我们在例子中使用到了number属性来判断get拿到的page信息,是否是当前页,如果是当前页,那么拿到的page就不会是一个链接,而是一个文字
4.4 常用方法
- has_next() 如果有下一页返回True
- has_previous() 如果有上一页返回True
- has_other_pages() 如果有上一页或下一页返回True
- next_page_number() 返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
- previous_page_number() 返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
我们在例子中,用到了has_next(),has_previous(),previous_page_number()和next_page_number()
5 案例分析
视图已经分析过了,我们现在来看test_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--显示内容-->
{% for content in current_page %}
<p>
{{ content }}
</p>
{% endfor %}
<!--判断是否有上一页,如果有上一页就显示上一页的链接,如果没有上一页就不显示,链接的href用当前页上一页的页码-->
{% if current_page.has_previous %}
<a href="/test_page?page={{ current_page.previous_page_number }}">上一页</a>
{% endif %}
<!--使用page_range拿到范围,判断每一个索引链接是否是当前页,如果是索引链接是一段文字,如果不是就是一个链接指向自身代表的页数-->
{% for current_page_num in paginator.page_range %}
{% if current_page_num == current_page.number %}
{{ current_page_num }}
{% else %}
<a href="/test_page?page={{ current_page_num }}">{{ current_page_num }}</a>
{% endif %}
{% endfor %}
<!--判断是否有下一页,如果有下一页就显示下一页的链接,如果没有下一页就不显示,链接的href用当前页下一页的页码-->
{% if current_page.has_next %}
<a href="/test_page?page={{ current_page.next_page_number }}">下一页</a>
{% endif %}
</body>
</html>
6 将数据换成从数据库拿出来的数据
只需要将这里换成查询数据的语句就可以了
之后我们就可以拿到数据了
可以根据字段拿到指定的数据,比如我现在要使用名字
这里就会显示名字了