---
title: "分页器"
version: 4.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.2/ref/paginator/
canonical: https://djangodocs.dev/zh-hans/4.2/ref/paginator/
---
# 分页器

Django 提供了一些类来帮助你管理分页数据 ——也就是说，数据被分割在几个页面上，并带有 “上一页／下一页” 的链接。这些类位于 [django/core/paginator.py](https://github.com/django/django/blob/stable/4.2.x/django/core/paginator.py) 中。

有关示例，请参阅 [分页主题指南](/zh-hans/4.2/topics/pagination/)。

## `Paginator` 类

#### `class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)`

当使用 `len()` 或直接迭代时，分页器的作用就像一个 [`Page`](#django.core.paginator.Page) 的序列。

#### `Paginator.object_list`

必要的。一个列表、元组、`QuerySet` 或其他具有 `count()` 或 `__len__()` 方法的可切片对象。为了实现一致的分页，`QuerySet` 应该是有序的，例如使用 [`order_by()`](/zh-hans/4.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by) 子句或使用模型上的默认 [`ordering`](/zh-hans/4.2/ref/models/options/#django.db.models.Options.ordering)。

> **对大型 QuerySet 进行分页的性能问题**
>
> 如果你使用的 `QuerySet` 有非常多的项目，在某些数据库上请求高页数可能会很慢，因为产生的 `LIMIT` ／ `OFFSET` 查询需要计算 `OFFSET` 记录的数量，随着页数的增加，需要的时间也就越长。

#### `Paginator.per_page`

必要的。一个页面中包含的最大项目数，不包括 orphans（参见下面的 [`orphans`](#django.core.paginator.Paginator.orphans) 可选参数）。

#### `Paginator.orphans`

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

#### `Paginator.allow_empty_first_page`

可选的。是否允许第一页为空。 如果 `False` 并且 `object_list` 是空的，则会出现 `EmptyPage` 错误。

### 方法

#### `Paginator.get_page(number)`

返回一个给定的基于 1 索引的 [`Page`](#django.core.paginator.Page) 对象，同时处理超出范围和无效的页码。

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

只有当你指定了 `Paginator(..., allow_empty_first_page=False)` 并且 `object_list` 为空时，才会引发 [`EmptyPage`](#django.core.paginator.EmptyPage) 异常。

#### `Paginator.page(number)`

返回一个带有给定的基于 1 的索引的 [`Page`](#django.core.paginator.Page) 对象。如果 `number` 无法通过调用 `int()` 转换为整数，则引发 [`PageNotAnInteger`](#django.core.paginator.PageNotAnInteger)。如果给定的页数不存在，则引发 [`EmptyPage`](#django.core.paginator.EmptyPage)。

#### `Paginator.get_elided_page_range(number, * (Keyword-only parameters separator (PEP 3102)), on_each_side=3, on_ends=2)`

返回一个基于 1 的页码列表，类似于 [`Paginator.page_range`](#django.core.paginator.Paginator.page_range)，但在 [`Paginator.num_pages`](#django.core.paginator.Paginator.num_pages) 很大时，可能会在当前页码的一侧或两侧添加省略号。

每个当前页码两侧包括的页数由 `on_each_side` 参数决定，默认为 3。

在页码范围的开头和结尾包括的页数由 `on_ends` 参数决定，默认为 2。

例如，如果 `on_each_side` 和 `on_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`](#django.core.paginator.InvalidPage) 异常。

### 属性

#### `Paginator.ELLIPSIS`

一个可翻译的字符串，用作 [`get_elided_page_range()`](#django.core.paginator.Paginator.get_elided_page_range) 返回的页面范围中省略的页码的替代物。默认值是 `'…'`。

#### `Paginator.count`

所有页面的对象总数。

> **Note**
>
> 在确定 `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`](#django.core.paginator.Paginator)，或使用 [`Paginator.page()`](#django.core.paginator.Paginator.page) 获得它们。

#### `class Page(object_list, number, paginator)`

当使用 `len()` 或直接迭代时，一个页面就像一个 [`Page.object_list`](#django.core.paginator.Page.object_list) 的序列。

### 方法

#### `Page.has_next()`

如果有下一页，返回 `True`。

#### `Page.has_previous()`

如果有上一页，返回 `True`。

#### `Page.has_other_pages()`

如果有下一页 **或** 上一页，返回 `True`。

#### `Page.next_page_number()`

返回下一页的页码。如果下一页不存在，则引发 [`InvalidPage`](#django.core.paginator.InvalidPage)。

#### `Page.previous_page_number()`

返回上一页的页码。如果上一页不存在，则引发 [`InvalidPage`](#django.core.paginator.InvalidPage)。

#### `Page.start_index()`

返回页面上第一个对象，相对于分页器列表中所有对象的基于 1 的索引。例如，当对一个有 5 个对象的列表进行分页时，每页有 2 个对象，第二页的 [`start_index()`](#django.core.paginator.Page.start_index) 将返回 `3`。

#### `Page.end_index()`

返回页面上最后一个对象相对于分页器列表中所有对象的基于 1 的索引。例如，当对一个有 5 个对象的列表进行分页时，每页有 2 个对象，第二页的 [`end_index()`](#django.core.paginator.Page.end_index) 将返回 `4`。

### 属性

#### `Page.object_list`

此页上的对象列表。

#### `Page.number`

此页的基于 1 的页码。

#### `Page.paginator`

关联的 [`Paginator`](#django.core.paginator.Paginator) 对象。

## 异常

#### `exception InvalidPage`

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

[`Paginator.page()`](#django.core.paginator.Paginator.page) 方法在请求的页面无效（即不是整数）或不包含任何对象时引发异常。一般来说，只要捕获 `InvalidPage` 异常就够了，但如果你想要更细化，你可以捕获以下任何一种异常。

#### `exception PageNotAnInteger`

当 [`page()`](#django.core.paginator.Paginator.page) 的值不是整数时发生该事件。

#### `exception EmptyPage`

当 [`page()`](#django.core.paginator.Paginator.page) 被赋予一个有效的值，但该页面上没有对象存在时，引发该异常。

这两个异常都是 [`InvalidPage`](#django.core.paginator.InvalidPage) 的子类，所以你可以用 `except InvalidPage` 处理这两个异常。
