分页器

Django 提供了一些类来帮助你管理分页数据——也就是跨多个页面拆分的、带有“上一页/下一页”链接的数据。这些类位于 django/core/paginator.py

有关示例,请参阅 分页主题指南

Paginator

class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True, error_messages=None)[source]

使用 len() 或直接迭代时,分页器就像一个 Page 序列。

Paginator.object_list

必需。一个列表、元组、QuerySet 或其他可切片的对象,具有 count()__len__() 方法。为了实现一致的分页,QuerySet 应已排序,例如,使用 order_by() 子句或模型上的默认 ordering

分页大型 QuerySet 时的性能问题

如果你使用的是具有大量项的 QuerySet,则请求高页码在某些数据库上可能会很慢,因为生成的 LIMIT/OFFSET 查询需要计算 OFFSET 记录的数量,随着页码的增加,这将花费更长的时间。

Paginator.per_page

必需。每页包含的最多项目数,不包括孤儿项(请参见下面的 orphans 可选参数)。

Paginator.orphans

可选。当你不希望最后一页只有很少的项目时使用。如果最后一页的项目数量通常小于或等于 orphans,则这些项目将添加到前一页(成为最后一页),而不是将这些项目单独留在一个页面上。例如,对于 23 个项目,per_page=10orphans=3,将有两页;第一页有 10 个项目,第二页(也是最后一页)有 13 个项目。orphans 默认值为零,这意味着页面永远不会合并,最后一页可能只有一个项目。

Paginator.allow_empty_first_page

可选。是否允许第一页为空。如果为 Falseobject_list 为空,则将引发 EmptyPage 错误。

Paginator.error_messages
Django 5.0 中新增。

error_messages 参数允许你覆盖分页器将引发的默认消息。传入一个字典,其键与要覆盖的错误消息匹配。可用的错误消息键为:invalid_pagemin_pageno_results

例如,这是默认错误消息

>>> from django.core.paginator import Paginator
>>> paginator = Paginator([1, 2, 3], 2)
>>> paginator.page(5)
Traceback (most recent call last):
  ...
EmptyPage: That page contains no results

这是一个自定义错误消息

>>> paginator = Paginator(
...     [1, 2, 3],
...     2,
...     error_messages={"no_results": "Page does not exist"},
... )
>>> paginator.page(5)
Traceback (most recent call last):
  ...
EmptyPage: Page does not exist

方法

Paginator.get_page(number)[source]

返回具有给定基于 1 的索引的 Page 对象,同时还处理超出范围和无效的页码。

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

仅当指定 Paginator(..., allow_empty_first_page=False)object_list 为空时,才会引发 EmptyPage 异常。

Paginator.page(number)[source]

返回具有给定基于 1 的索引的 Page 对象。如果无法通过调用 int()number 转换为整数,则引发 PageNotAnInteger。如果给定的页码不存在,则引发 EmptyPage

Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)[source]

返回类似于 Paginator.page_range 的基于 1 的页码列表,但当 Paginator.num_pages 很大时,可能会在当前页码的两侧或任一侧添加省略号。

要在当前页码两侧包含的页数由 on_each_side 参数确定,默认为 3。

要在页码范围的开头和结尾包含的页数由 on_ends 参数确定,默认为 2。

例如,使用 on_each_sideon_ends 的默认值,如果当前页码为 10 并且共有 50 页,则页码范围将为 [1, 2, '…', 7, 8, 9, 10, 11, 12, 13, '…', 49, 50]。这将导致页码 7、8 和 9 在当前页码的左侧,页码 11、12 和 13 在当前页码的右侧,以及开头处的页码 1 和 2 以及结尾处的页码 49 和 50。

如果给定的页码不存在,则引发InvalidPage

属性

Paginator.ELLIPSIS

一个可翻译的字符串,用作get_elided_page_range()返回的页码范围中省略页码的替代。默认为'…'

Paginator.count[source]

所有页面的对象总数。

注意

在确定object_list中包含的对象数量时,Paginator将首先尝试调用object_list.count()。如果object_list没有count()方法,则Paginator将回退到使用len(object_list)。这允许诸如QuerySet之类的对象在可用时使用更高效的count()方法。

Paginator.num_pages[source]

总页数。

Paginator.page_range[source]

一个基于1的页码范围迭代器,例如产生[1, 2, 3, 4]

Page

你通常不会手动构造Page对象——你会通过迭代Paginator或使用Paginator.page()来获得它们。

class Page(object_list, number, paginator)[source]

使用len()或直接迭代它时,页面就像Page.object_list的序列。

方法

Page.has_next()[source]

如果存在下一页,则返回True

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的索引,相对于分页器列表中的所有对象。例如,当分页包含5个对象的列表,每个页面2个对象时,第二页的start_index()将返回3

Page.end_index()[source]

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

属性

Page.object_list

此页面上的对象列表。

Page.number

此页面的基于1的页码。

Page.paginator

关联的Paginator对象。

异常

exception InvalidPage[source]

当分页器传递无效页码时引发的异常的基类。

如果请求的页面无效(即不是整数)或不包含任何对象,则Paginator.page()方法会引发异常。通常,捕获InvalidPage异常就足够了,但如果您需要更细粒度的控制,您可以捕获以下任何异常

exception PageNotAnInteger[source]

page()给定的值不是整数时引发。

exception EmptyPage[source]

page()给定一个有效值,但在该页面上不存在对象时引发。

这两个异常都是InvalidPage的子类,因此您可以使用except InvalidPage来处理它们。

返回顶部