django 1.8 官方文档翻译:13-6 分页

分页

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
>>> p.page_range
[1, 2]

>>> 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(),接着如果传入的对象没有count()方法则回退调用 len()。这样会使类似于Django的QuerySet的对象使用更加高效的 count()方法,如果存在的话。

使用 Paginator

这里有一些复杂一点的例子,它们在视图中使用 Paginator 来为查询集分页。我们提供视图以及相关的模板来展示如何展示这些结果。这个例子假设你拥有一个已经导入的Contacts模型。

视图函数看起来像是这样:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page

    page = request.GET.get('page')
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        contacts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages)

    return render_to_response('list.html', {"contacts": contacts})

list.html模板中,你会想要包含页面之间的导航,以及来自对象本身的任何有趣的信息:


<div class="pagination">
    <span class="step-links">

        <span class="current">
            Page  of .
        </span>

    </span>
</div>

Paginator objects

Paginator类拥有以下构造器:

_class _Paginator(_object_list_, _per_page_, _orphans=0_, _allow_empty_first_page=True_)[source]

所需参数

object_list

A list, tuple, Django QuerySet, or other sliceable object with a
count() or __len__() method.

per_page

The maximum number of items to include on a page, not including orphans
(see the orphans optional argument below).

可选参数

orphans

The minimum number of items allowed on the last page, defaults to zero.
Use this when you don’t want to have a last page with very few items.
If the last page would normally have a number of items less than or equal
to orphans, then those items will be added to the previous page (which
becomes the last page) instead of leaving the items on a page by
themselves. For example, with 23 items, per_page=10, and
orphans=3, there will be two pages; the first page with 10 items and
the second (and last) page with 13 items.

allow_empty_first_page

Whether or not the first page is allowed to be empty. If False and
object_list is empty, then an EmptyPage error will be raised.

方法

Paginator.`page`(_number_)[source]

返回在提供的下标处的Page对象,下标以1开始。如果提供的页码不存在,抛出InvalidPage异常。

属性

Paginator.`count`

所有页面的对象总数。

注意

当计算object_list所含对象的数量时, Paginator会首先尝试调用object_list.count()。如果object_list没有 count() 方法,Paginator 接着会回退使用len(object_list)。这样会使类似于Django’s QuerySet的对象使用更加便捷的count()方法,如果存在的话。

Paginator.`num_pages`

页面总数。

Paginator.`page_range`

页码的范围,从1开始,例如[1, 2, 3, 4]

InvalidPage exceptions

_exception _InvalidPage[source]

异常的基类,当paginator传入一个无效的页码时抛出。

Paginator.page()放回在所请求的页面无效(比如不是一个整数)时,或者不包含任何对象时抛出异常。通常,捕获InvalidPage异常就够了,但是如果你想更加精细一些,可以捕获以下两个异常之一:

_exception _PageNotAnInteger[source]

当向page()提供一个不是整数的值时抛出。

_exception _EmptyPage[source]

当向page()提供一个有效值,但是那个页面上没有任何对象时抛出。

这两个异常都是InvalidPage的子类,所以你可以通过简单的except InvalidPage来处理它们。

Page objects

你通常不需要手动构建 Page对象 — 你可以从Paginator.page()来获得它们。

_class _Page(_object_list_, _number_, _paginator_)[source]

当调用len()或者直接迭代一个页面的时候,它的行为类似于 Page.object_list 的序列。

方法

Page.`has_next`()[source]

Returns True if there’s a next page.

Page.`has_previous`()[source]

如果有上一页,返回 True

Page.`has_other_pages`()[source]

如果有上一页_或_下一页,返回True

Page.`next_page_number`()[source]

返回下一页的页码。如果下一页不存在,抛出InvalidPage异常。

Page.`previous_page_number`()[source]

返回上一页的页码。如果上一页不存在,抛出InvalidPage异常。

Page.`start_index`()[source]

返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3

Page.`end_index`()[source]

返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index() 会返回 4

属性

Page.`object_list`

当前页上所有对象的列表。

Page.`number`

当前页的序号,从1开始。

Page.`paginator`

相关的Paginator对象。

译者:Django 文档协作翻译小组,原文:Pagination

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

    原文作者:飞龙
    原文地址: https://segmentfault.com/a/1190000003761879
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞