Django——Paginator分页器
Paginator分页器
1 | class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True, error_messages=None) |
Django提供的可以帮我们管理分页数据的分页器类。
一般情况下使用Paginator(object_list, per_page)方法。
参数
Paginator.object_list
必要参数。object_lsit指的是列表、元组、QuerySet或者其他具有count()或__len__()方法的可切片的对象。
为了实现一致的分页,QuerySet应该是有序的,可以使用order_by()子句或者使用模型默认的ordering(如主键的id顺序)。
Paginator.per_page
必要参数。指一页可以包含的最大项目数。注意不包括orphans参数。
Paginator.orphans
可选参数。若不希望最后一页的数据很少时可用。若最后一页的项目数<= orphans,那么这些项目将被添加到前一页成为最后一页,不让他们单独留在一页。
Paginator.allow_empty_first_page
可选参数。是否允许第一页为空。若Flase且object_list为空,则会出现EmptyPage错误。
Paginator.error_messages
Diango 5.0新增。可选参数。该参数允许覆盖分页器将引发的默认消息。传入字典,字典的键与覆盖的消息相匹配。可选择的错误消息键包括:invalid_page、min_page和no_results。
示例:
1 | paginator = Paginator( |
当我们访问paginator.page(5)时会引发error_messages异常,输出EmptyPage: Page does not exist。
属性
Paginator.ELLIPSIS
一个可翻译的字符串,用作get_elided_page_range()返回的页面范围中省略的页码的替代物。默认值为'...'。
Paginator.count
所有的页面的对象总数。
注:
确定object_list中包含的对象数量时,Paginator会首先尝试调用objecct_list.count()。
如果object_list()没有count()方法,那么Paginator将回到使用len(object_list)。
也就是说允许对象比如QuerySet在可用时使用更高效的count()方法。
Paginator.num_pages
总页数。
Paginator.page_range
以1为基础的页码范围迭代器,如产生[1, 2, 3, 4]。
方法
Paginator.get_page(number)
返回一个有效的页面,即使number参数不是数字或不在范围内。
或者说返回一个给定的基于1索引的Page对象,同时可以处理超出范围以及无效的页码。
具体的处理流程为:
先验证number是否是可允许的number(不是float类型以及非integer类型;1 < number < num_pages)如果出现PageNotAnInteger异常,就给number赋值为1;如果出现EmptyPage异常,就给number赋值为self.num_pages,最后返回的时候调用self.page(number)方法。
isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。
Paginator.page(number)
返回一个给定的基于1的索引的Page对象。
具体的处理流程为:
先验证number是否为有效的值(不是float类型以及非integer类型;1 < number < num_pages),然后计算当前页的底部bottom(如(5 - 1) * 10 # number为5,per_page为10)和顶部top(bottom + 10)。
再计算顶部top + orphans 是否>= self.count,若大于等于时,顶部就设置为self.count。此时就是用orphans判断最后一页的数据是否太少了,如果太少了就把top赋值为self.count,最后返回self._get_page(self.object_list[bottom:top], number, self)获取Page对象。
Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)
返回一个基于1的页码列表,类似于Paginator.page_range,但如果Paginator.num_pages很大时,可能会在当前页码的一侧或两侧添加省略号。
每个当前页码两侧包括的页数由on_each_side参数决定,默认为 3。
在页码范围的开头和结尾包括的页数由 on_ends 参数决定,默认为 2。
如果给定的页码不存在,则引发 InvalidPage 异常。
Page类
提到Paginator就不得不得提到Page类。一般情况下我们只会通过迭代Paginator或者使用Paginator.page()来获得Page类。
1 | class Page(object_list, number, paginator) |
属性
Page.object_list
得到该页的对象列表
Page.number
得到此页基于 1 的页码
Page.paginator
关联的Paginator对象
方法
Page.has_next()
如果有下一页,返回True
Page.has_privious()
如果有上一页,返回True
Page.has_other_pages()
如果有下一页或上一页,返回True
Page.next_page_number()
返回下一页的页码,如果下一页不存在,则引发InvaliPage
Page.previous_page_number()
返回上一页的页码。如果上一页不存在,则引发InvaliPage错误。
Page.start_index()
返回页面上第一个对象,相对于分页器列表中所有对象的基于1的索引,如果分页器中没有数据,会直接返回0。例如,当对一个有5个对象的列表进行分页时,每页有两个对象,第二页的start_index()将返回3。
Page.end_index()
返回页面上最后一个对象相对于分页器列表中所有对象的基于1的索引。例如,当对一个有5个对象的列表进行分页时,每页有两个对象,第二页的end_index()将返回4。
