分页器

Django 提供了一些类来帮助你管理分页数据,即跨越多页的数据,带有“上一个/下一个”链接。这些类位于 django/core/paginator.py 中。

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

Paginator

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

使用 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)

返回一个 Page 对象,其 1 为基础的索引为给定值,同时还处理超出范围和无效的页码。

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

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

Paginator.page(number)

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

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

返回类似于 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

所有页面上的对象总数。

注意

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

Paginator.num_pages

总页数。

Paginator.page_range

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

Page

通常不会手动构造 Page 对象,而是通过迭代 Paginator 或使用 Paginator.page() 来获取。

class Page(object_list, number, paginator)

使用 len() 或直接迭代时,页面表现得像 Page.object_list 序列。

方法

Page.has_next()

如果有下一页,则返回 True

Page.has_previous()

如果有上一页,则返回 True

Page.has_other_pages()

如果有下一页上一页,则返回 True

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

属性

Page.object_list

此页面上的对象列表。

Page.number

此页面的基于 1 的页号。

Page.paginator

关联的 Paginator 对象。

异常

exception InvalidPage

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

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

exception PageNotAnInteger

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

exception EmptyPage

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

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

返回顶部