Django之自带分页模块Pagination
Django提供了一些类来帮助您管理分页数据 - 即分布在多个页面上的数据,使用“上一页/下一页”链接。这些课程都在django/core/paginator.py
。
Example¶
给Paginator
对象的列表,再加上你想有每个页面上的项目数,和它给你访问的每个页面的项目方法:
>>> from django.core.paginator import Paginator >>> objects = ['john', 'paul', 'george', 'ringo'] >>> p = Paginator(objects, 2) >>> p.count 4 >>> p.num_pages 2 >>> type(p.page_range) <class 'range_iterator'> >>> p.page_range range(1, 3) >>> page1 = p.page(1) >>> page1 <Page 1 of 2> >>> page1.object_list ['john', 'paul'] >>> page2 = p.page(2) >>> page2.object_list ['george', 'ringo'] >>> page2.has_next() False >>> page2.has_previous() True >>> page2.has_other_pages() True >>> page2.next_page_number() Traceback (most recent call last): ... EmptyPage: That page contains no results >>> page2.previous_page_number() 1 >>> page2.start_index() # The 1-based index of the first item on this page 3 >>> page2.end_index() # The 1-based index of the last item on this page 4 >>> p.page(0) Traceback (most recent call last): ... EmptyPage: That page number is less than 1 >>> p.page(3) Traceback (most recent call last): ... EmptyPage: That page contains no results
注意 请注意,您可以使用或方法提供Paginator列表/元组,Django QuerySet或任何其他对象。在确定传递的对象中包含的对象数时, 将首先尝试调用,然后如果传递的对象没有方法则回退到使用 。这允许诸如Django之类的对象 在可用时使用更有效的方法。count()__len__()Paginatorcount()len()count()QuerySetcount()
Paginator
在视图中使用¶
这是一个稍微复杂的示例,用于Paginator
在视图中对查询集进行分页。我们同时提供视图和附带的模板,以显示如何显示结果。此示例假定您具有Contacts
已导入的 模型。
视图函数如下所示:
from django.core.paginator import Paginator from django.shortcuts import render def listing(request): contact_list = Contacts.objects.all() paginator = Paginator(contact_list, 25) # Show 25 contacts per page page = request.GET.get('page') contacts = paginator.get_page(page) return render(request, 'list.html', {'contacts': contacts})
在模板中list.html
,您需要在页面之间包含导航以及来自对象本身的任何有趣信息:
{% for contact in contacts %} {# Each "contact" is a Contact model object. #} {{ contact.full_name|upper }}<br> ... {% endfor %} <div class="pagination"> <span class="step-links"> {% if contacts.has_previous %} <a href="?page=1">« first</a> <a href="?page={{ contacts.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. </span> {% if contacts.has_next %} <a href="?page={{ contacts.next_page_number }}">next</a> <a href="?page={{ contacts.paginator.num_pages }}">last »</a> {% endif %} </span> </div>
Paginator
objects¶
该Paginator
班有这样的构造函数:
必需参数¶
object_list
-
QuerySet
带有count()
或__len__()
方法的列表,元组或其他可切片对象。对于一致的分页,QuerySet
应该对s进行排序,例如使用模型中的order_by()
子句或默认值ordering
。分散大
QuerySet
s的性能问题如果您使用的是
QuerySet
具有大量项目的项目,则在某些数据库上请求高页码可能会很慢,因为结果LIMIT
/OFFSET
查询需要计算OFFSET
在页码数越来越高时需要更长时间的 记录数。 per_page
- 页面上包含的最大项目数,不包括孤儿(请参阅
orphans
下面的可选参数)。
可选参数¶
orphans
- 如果您不希望最后一页包含很少的项目,请使用此选项。如果最后一页通常具有小于或等于的项目数
orphans
,那么这些项目将被添加到上一页面(成为最后一页),而不是将这些项目自己留在页面上。例如,有23个项目,per_page=10
和orphans=3
,将有两个页面; 第一页有10个项目,第二页(和最后一页)有13个项目。orphans
默认为零,这意味着页面永远不会合并,最后一页可能有一个项目。 allow_empty_first_page
- 是否允许第一页为空。如果为
False
和object_list
空,则会引发EmptyPage
错误。
InvalidPage
exceptions¶
Paginator.page()
如果请求的页面无效(即,不是整数)或不包含任何对象,则该方法引发异常。通常,它足以捕获InvalidPage
异常,但如果您想要更多粒度,则可以捕获以下任一异常:
这两个例外都是子类InvalidPage
,所以你可以用简单的方法处理它们。except InvalidPage
Page
objects¶
您通常不会Page
手工构建对象 - 您将使用它们Paginator.page()
。
- class
Page
(object_list,number,paginator)[source] ¶ -
页面的作用类似于直接
Page.object_list
使用len()
或迭代它的顺序。
Methods¶
Page.
next_page_number
()[来源] ¶-
返回下一页编号。
InvalidPage
如果下一页不存在则引发。
Page.
previous_page_number
()[来源] ¶-
返回上一页编号。
InvalidPage
如果前一页不存在则引发。
Page.
start_index
()[来源] ¶-
返回页面上第一个对象的从1开始的索引,相对于分页器列表中的所有对象。例如,当为每页包含2个对象的5个对象的列表进行分页时,
start_index()
将返回第二个页面3
。
Page.
end_index
()[来源] ¶-
返回页面上最后一个对象的从1开始的索引,相对于分页器列表中的所有对象。例如,当为每页包含2个对象的5个对象的列表进行分页时,
end_index()
将返回第二个页面4
。