# Django 5.2.8 documentation

# 分页器

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（参见下面的 `orphans` 可选参数）。

Paginator.orphans

  Optional. 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. `orphans` defaults to zero, which means pages are never combined and the last page may have one item. `orphans` should be less than the `per_page` value.

  Deprecated since version 6.0: Support for the `orphans` argument being larger than or equal to the `per_page` argument is deprecated.

Paginator.allow_empty_first_page

  Optional. 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.error_messages

  `error_messages` 参数允许你覆盖分页器将引发的默认消息。传入一个字典，其中的键与你想要覆盖的错误消息相匹配。可用的错误消息键包括：`invalid_page`、`min_page` 和 `no_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)

  返回一个给定的基于 1 索引的 `Page` 对象，同时处理超出范围和无效的页码。

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

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

Paginator.page(number)

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

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

  返回一个基于 1 的页码列表，类似于 `Paginator.page_range`，但在 `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` 异常。

### 属性

Paginator.ELLIPSIS

  一个可翻译的字符串，用作 `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]`。

## `AsyncPaginator` class

New in Django 6.0.

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

  Asynchronous version of `Paginator`.

  `AsyncPaginator` has the same attributes and signatures as `Paginator`, with the following exceptions:

  - The attribute `Paginator.count` is supported as an asynchronous method `AsyncPaginator.acount()`.

  - The attribute `Paginator.num_pages` is supported as an asynchronous method `AsyncPaginator.anum_pages()`.

  - The attribute `Paginator.page_range` is supported as an asynchronous method `AsyncPaginator.apage_range()`.

  `AsyncPaginator` has asynchronous versions of the same methods as `Paginator`, using an `a` prefix - for example, use `await async_paginator.aget_page(number)` rather than `paginator.get_page(number)`.

## `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 的索引。例如，当对一个有 5 个对象的列表进行分页时，每页有 2 个对象，第二页的 `start_index()` 将返回 `3`。

Page.end_index()

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

### 属性

Page.object_list

  此页上的对象列表。

Page.number

  此页的基于 1 的页码。

Page.paginator

  关联的 `Paginator` 对象。

## `AsyncPage` class

New in Django 6.0.

class AsyncPage(object_list, number, paginator)

  Asynchronous version of `Page`.

  `AsyncPage` has the same attributes and signatures as `Page`, as well as asynchronous versions of all the same methods, using an `a` prefix - for example, use `await async_page.ahas_next()` rather than `page.has_next()`.

  `AsyncPage` has the following additional method:

  aget_object_list()

    Returns `AsyncPage.object_list` as a list. This method must be awaited before `AsyncPage` can be treated as a sequence of `AsyncPage.object_list`.

## 异常

exception InvalidPage

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

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

exception PageNotAnInteger

  当 `page()` 的值不是整数时发生该事件。

exception EmptyPage

  当 `page()` 被赋予一个有效的值，但该页面上没有对象存在时，引发该异常。

这两个异常都是 `InvalidPage` 的子类，所以你可以用 `except InvalidPage` 处理这两个异常。