Pagination
Django提供了几个类来帮助你管理分页数据 . 这些类在 django/core/paginator.py中.
Example
给Paginator一个列表对象,并添加每页显示的多少条数据,它就能给你提供访问每页的数据.
注意:你可以给Paginator一个列表/元组的数据对象,Django的QuerySet得到的数据,或者是一个含有count() 或 __len__()方法的对象.当物体的数量包含在传递过来的对象中时,Paginator首先会调用count方法.如果没有才会去查找len方法.
Using Paginator in a view
下面有一个展示Paginatior在View中使用的例子,将向你展示如何使用Paginator并且在页面中显示结果.
View中的函数部分:
在templates下的list.html中.你需要有一个导航条来,并设置加载传递过来的数据.
现在来详细介绍一下Paginator中的一些相关属性:
Paginator 对象
Paginator对象有一个构造器:
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
必须参数:
object_list
可选参数:
Methods
Paginator.page(number)Attributes
-
Paginator.num_pages
该属性返回总页数
-
Paginator.page_range
该属性返回一个页号的范围.例如[1,2,3,4]
Page 对象
通常我们不会去直接通过构造器去创建该对象,而是通过 Pagintor.page()方法获取. Page构造器: class Page(object_list, number, paginator)Methods
-
Page.has_next()
-
返回True表示有下一页
-
Page.has_previous()
-
Returns True 表示有前一页
-
Page.has_other_pages()
-
返回True表示有下一页或者前一页
-
Page.next_page_number()
-
返回下一页页号. 如果页号不存在则抛出 InvalidPage 异常
-
Page.previous_page_number()
-
返回前一页页号. 如果页号不存在则抛出 InvalidPage 异常
-
Page.start_index()
-
返回当前页面对象的开始下标,例如:当一个Paginator中有5个对象且每页显示2个则第二页的 start_index() 将返回3.
-
Page.end_index()
-
返回当前页面的结束下标. 例如:当一个Paginator中有5个对象且每页显示2个则第二页的 end_index() 将返回4.
-
Attributes
-
Page.object_list
-
当前页的列表数据对象
-
Page.number
-
当前页的页号
-
Page.paginator
-
关联的Paginator对象.
值的注意的是:Django的这种分页采用的是内存分页.对于数据量很大的情况来说很不合适,因为他每次都要去把所有的数据预先给加载进来,例如我只要看第一页的10条数据,但是在后台它却查了所有数据,大大降低的访问性能,这很不好.所以一般我们都是才会数据库分页.例如:在查询数据的时候:我们使用的是QuerySet的API来查询的之前我们是这样做的:
Contact.objects.all()
该方法 会查询所有的数据.而我们只想查询第一页的10条数据怎么写呢?可以这样做:
contects=Contact.objects.all()[0:10]
注意不能这样写:
contacts=Contact.object.all()
contacts=contacts[0:20]
这两种写法是有区别的:
前者利用QuerySets的惰性,这意味着只在对数据库进行求值之后才会对它们执行查询,这比立即查询的速度更快。这种惰性利用python的分片功能,Contact.objects.all()[0:20]在实际查询中用0作为offset,20作为limit,这样的查询可以极大提高查询性能。参考博文(http://www.redicecn.com/html/blog/Django/2011/0502/268.html)
而后者Contact.objects.all()是先从数据库中将所有数据查询出来,然后再contacts[0:20]进行分片,这简直太浪费电了,太不环保了。
这样我们就可以分页查询部分的数据,大大的提高了效率.但是此时我们已经不能再使用Django内置的Paginator来分页了.但是我们可以自己写一个Paginator类来实现我们自己的分页.