Django 2.2.4.dev20190701100356 文档

分页

Django提供了一些类来帮助您管理分页数据——也就是说,通过“上一页/下一页”链接拆分的数据。这些班住在 django/core/paginator.py .

例子

给予 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 或具有 count()__len__() 方法。确定传递对象中包含的对象数时, Paginator 会先调用吗 count() ,然后回退到使用 len() 如果传递的对象没有 count() 方法。这允许像Django这样的对象 QuerySet 使用更高效的 count() 方法(如果可用)。

使用 Paginator 从一个角度

下面是一个稍微复杂一点的示例,使用 Paginator 以便对查询集分页。我们提供视图和附带的模板来显示如何显示结果。此示例假定您有 Contacts 已导入的模型。

View函数如下所示:

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">&laquo; 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 &raquo;</a>
        {% endif %}
    </span>
</div>

Paginator 对象

这个 Paginator 类具有此构造函数:

class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)[源代码]

必需的参数

object_list

列表,元组, QuerySet 或具有 count()__len__() 方法。为了一致的分页, QuerySet 应订购S,例如 order_by() 条款或违约 ordering 模型上。

性能问题大 QuerySet 的S

如果你用的是 QuerySet with a very large number of items, requesting high page numbers might be slow on some databases, because the resulting LIMIT/OFFSET 查询需要计数 OFFSET 页号越大,所需时间越长的记录。

per_page
页面上要包含的最大项目数,不包括孤立项(请参见 orphans 以下是可选参数)。

可选参数

orphans
当您不希望最后一页只有很少的项目时,可以使用此选项。如果最后一页的项目数通常小于或等于 orphans 然后,这些项目将被添加到上一页(这将成为最后一页),而不是将项目单独留在一页上。例如,有23个项目, per_page=10orphans=3 有两页,第一页有10个项目,第二页(和最后一页)有13个项目。 orphans 默认为零,这意味着永远不会合并页面,最后一页可能有一个项目。
allow_empty_first_page
第一页是否允许为空。如果 Falseobject_list 是空的,然后是 EmptyPage 将引发错误。

方法

Paginator.get_page(number)[源代码]

返回A Page 对象,同时处理超出范围和无效的页码。

如果页面不是数字,则返回第一页。如果页码为负数或大于页数,则返回最后一页。

它引发了一个例外 (EmptyPage )仅当您指定 Paginator(..., allow_empty_first_page=False) 以及 object_list 是空的。

Paginator.page(number)[源代码]

返回A Page 具有给定的基于1的索引的对象。加薪 InvalidPage 如果给定的页码不存在。

属性

Paginator.count

所有页面上的对象总数。

注解

确定包含在 object_listPaginator 会先调用吗 object_list.count() .如果 object_list 没有 count() 方法,然后 Paginator 将回退到使用 len(object_list) . 这允许对象,如Django的 QuerySet ,使用更高效的 count() 方法(如果可用)。

Paginator.num_pages

总页数。

Paginator.page_range

基于1的页码范围迭代器,例如, [1, 2, 3, 4] .

InvalidPage 例外

exception InvalidPage[源代码]

paginator传递无效页码时引发的异常的基类。

这个 Paginator.page() 方法在请求的页无效(即不是整数)或不包含对象时引发异常。一般来说,它足以捕捉 InvalidPage 异常,但如果您想要更大的粒度,可以捕获以下任一异常:

exception PageNotAnInteger[源代码]

提出时 page() 给定的值不是整数。

exception EmptyPage[源代码]

提出时 page() 提供了一个有效值,但该页上不存在任何对象。

这两个异常都是 InvalidPage ,这样您就可以用一个简单的 except InvalidPage .

Page 对象

你通常不会建造 Page 用手拿东西——你可以用 Paginator.page() .

class Page(object_list, number, paginator)[源代码]

一页就像一个序列 Page.object_list 使用时 len() 或者直接迭代。

方法

Page.has_next()[源代码]

返回 True 如果有下一页。

Page.has_previous()[源代码]

返回 True 如果有上一页。

Page.has_other_pages()[源代码]

返回 True 如果有下一个 or 上一页。

Page.next_page_number()[源代码]

返回下一个页码。加薪 InvalidPage 如果下一页不存在。

Page.previous_page_number()[源代码]

返回上一个页码。加薪 InvalidPage 如果上一页不存在。

Page.start_index()[源代码]

返回页面上第一个对象相对于分页器列表中所有对象的1基索引。例如,当将5个对象的列表分页为每页2个对象时,第二页的 start_index() 会回来 3 .

Page.end_index()[源代码]

返回页面上最后一个对象相对于分页器列表中所有对象的1基索引。例如,当将5个对象的列表分页为每页2个对象时,第二页的 end_index() 会回来 4 .

属性

Page.object_list

此页上的对象列表。

Page.number

此页基于1的页码。

Page.paginator

相关的 Paginator 对象。