# Django 2.2.9.dev20191202104323 文档

# 分页

Django provides a few classes that help you manage paginated data -- that is, data that's split across several pages, with "Previous/Next" links. These classes live in `django/core/paginator.py`.

## 例如

Give `Paginator` a list of objects, plus the number of items you'd like to have on each page, and it gives you methods for accessing the items for each page:

    >>> from django.core.paginator import Paginator
    >>> objects = ['john', 'paul', 'george', 'ringo']
    >>> p = Paginator(objects, 2)

    >>> p.count
    4
    >>> p.num_pages
    2
    >>> type(p.page_range)
    <class 'range_iterator'>
    >>> p.page_range
    range(1, 3)

    >>> 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

注解

Note that you can give `Paginator` a list/tuple, a Django `QuerySet`, or any other object with a `count()` or `__len__()` method. When determining the number of objects contained in the passed object, `Paginator` will first try calling `count()`, then fallback to using `len()` if the passed object has no `count()` method. This allows objects such as Django's `QuerySet` to use a more efficient `count()` method when available.

## 在视图中使用 `Paginator`

Here's a slightly more complex example using `Paginator` in a view to paginate a queryset. We give both the view and the accompanying template to show how you can display the results. This example assumes you have a `Contacts` model that has already been imported.

The view function looks like this:

    from django.core.paginator import Paginator
    from django.shortcuts import render

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

        page = request.GET.get('page')
        contacts = paginator.get_page(page)
        return render(request, 'list.html', {'contacts': contacts})

In the template `list.html`, you'll want to include navigation between pages along with any interesting information from the objects themselves:

    {% for contact in contacts %}
        {# Each "contact" is a Contact model object. #}
        {{ contact.full_name|upper }}<br>
        ...
    {% endfor %}

    <div class="pagination">
        <span class="step-links">
            {% if contacts.has_previous %}
                <a href="?page=1">&laquo; first</a>
                <a href="?page={{ contacts.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
            </span>

            {% if contacts.has_next %}
                <a href="?page={{ contacts.next_page_number }}">next</a>
                <a href="?page={{ contacts.paginator.num_pages }}">last &raquo;</a>
            {% endif %}
        </span>
    </div>

## `Paginator` 对象

`Paginator` 类的构造方法是:

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

### 必选参数

`object_list`

  A list, tuple, `QuerySet`, or other sliceable object with a `count()` or `__len__()` method. For consistent pagination, `QuerySet`s should be ordered, e.g. with an `order_by()` clause or with a default `ordering` on the model.

  Performance issues paginating large `QuerySet`s

  If you're using a `QuerySet` with a very large number of items, requesting high page numbers might be slow on some databases, because the resulting `LIMIT`/`OFFSET` query needs to count the number of `OFFSET` records which takes longer as the page number gets higher.

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

### 可选参数

`orphans`
  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.
`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.``get_page`(number)

  Returns a `Page` object with the given 1-based index, while also handling out of range and invalid page numbers.

  If the page isn't a number, it returns the first page. If the page number is negative or greater than the number of pages, it returns the last page.

  It raises an exception (`EmptyPage`) only if you specify `Paginator(..., allow_empty_first_page=False)` and the `object_list` is empty.

`Paginator.``page`(number)

  Returns a `Page` object with the given 1-based index. Raises `InvalidPage` if the given page number doesn't exist.

### 属性

`Paginator.``count`

  The total number of objects, across all pages.

  注解

  When determining the number of objects contained in `object_list`, `Paginator` will first try calling `object_list.count()`. If `object_list` has no `count()` method, then `Paginator` will fallback to using `len(object_list)`. This allows objects, such as Django's `QuerySet`, to use a more efficient `count()` method when available.

`Paginator.``num_pages`

  The total number of pages.

`Paginator.``page_range`

  A 1-based range iterator of page numbers, e.g. yielding `[1, 2, 3, 4]`.

## `InvalidPage` exceptions

exception `InvalidPage`

  当paginator对象试图访问无效页码时引发异常的基类。

The `Paginator.page()` method raises an exception if the requested page is invalid (i.e., not an integer) or contains no objects. Generally, it's enough to catch the `InvalidPage` exception, but if you'd like more granularity, you can catch either of the following exceptions:

exception `PageNotAnInteger`

  Raised when `page()` is given a value that isn't an integer.

exception `EmptyPage`

  Raised when `page()` is given a valid value but no objects exist on that page.

Both of the exceptions are subclasses of `InvalidPage`, so you can handle them both with a simple `except InvalidPage`.

## `Page` objects

你通常不会手动实例化Page对象 - 你会使用方法Paginator.page()。

class `Page`(object_list, number, paginator)

  A page acts like a sequence of `Page.object_list` when using `len()` or iterating it directly.

### 方法

`Page.``has_next`()

  Returns `True` if there's a next page.

`Page.``has_previous`()

  Returns `True` if there's a previous page.

`Page.``has_other_pages`()

  Returns `True` if there's a next or previous page.

`Page.``next_page_number`()

  Returns the next page number. Raises `InvalidPage` if next page doesn't exist.

`Page.``previous_page_number`()

  Returns the previous page number. Raises `InvalidPage` if previous page doesn't exist.

`Page.``start_index`()

  Returns the 1-based index of the first object on the page, relative to all of the objects in the paginator's list. For example, when paginating a list of 5 objects with 2 objects per page, the second page's `start_index()` would return `3`.

`Page.``end_index`()

  Returns the 1-based index of the last object on the page, relative to all of the objects in the paginator's list. For example, when paginating a list of 5 objects with 2 objects per page, the second page's `end_index()` would return `4`.

### 属性

`Page.``object_list`

  此页上的对象列表。

`Page.``number`

  此页的基于 1 的页码。

`Page.``paginator`

  关联的 `Paginator` 对象。