Django——Paginator分页器
Paginator
分页器
1 |
|
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.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 |
|
属性
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
。