---
title: "ページネーション"
version: 2.0
locale: ja
source: https://docs.djangoproject.com/ja/2.0/topics/pagination/
canonical: https://djangodocs.dev/ja/2.0/topics/pagination/
---
# ページネーション

Django はページネーションしたデータの管理を助けるクラスを提供しています。つまり、データをいくつかのページに分割して、「戻る/次へ」リンクを使って移動できるようにします。これらのクラスは `django/core/paginator.py` で実装されています。

## カスタマイズ例

[`Paginator`](#django.core.paginator.Paginator) にオブジェクトのリストと、各ページに持たせたいアイテムの数を与えてください。すると、各ページのアイテムにアクセスできるメソッドが使えるようになります。

```
>>> 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**
>
> `Paginator` には、リストやタプル、 Django の `QuerySet`、`count()` または `__len__()` メソッドを持つどんなオブジェクトでも与えることができます。渡されたオブジェクトに含まれるオブジェクト数を特定するとき、`Paginator` は最初に `count()` メソッドの実行を試み、その後、渡されたオブジェクトが `count()` メソッドを実装していなかった場合のフォールバックとして `len()` を使用します。この工夫により、Djangoの `QuerySet` などで、より効率のよい `count()` メソッドを利用できます。

## `Paginator` をビューで使用する

次は、ビューの中で queryset をページネーションするために [`Paginator`](#django.core.paginator.Paginator) を使用する、もう少し複雑な例を見てみましょう。ページネーションの結果を表示する方法を見せるために、ビューとテンプレートの両方を示します。この例では、`Contacts` モデルはあらかじめインポートされているものとします。

ビュー関数は次のようになります。

```
from django.core.paginator import EmptyPage, PageNotAnInteger, 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:

```html+django
{% 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`](#django.core.paginator.Paginator) には次のようなコンストラクタがあります。

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

### Required arguments

**`object_list`**

  リスト、タプル、`QuerySet`、あるいはその他のスライス可能なオブジェクトで、`count()` または `__len__()` を実装しているオブジェクトを指定します。一貫性のあるページネーションのためには、`QuerySet` は並び替えられていなければなりません。たとえば、[`order_by()`](/ja/2.0/ref/models/querysets/#django.db.models.query.QuerySet.order_by) 句を使用したり、モデルでデフォルトの [`ordering`](/ja/2.0/ref/models/options/#django.db.models.Options.ordering) を指定します。

  > **巨大な QuerySet のページネーションによるパフォーマンス上の問題**
  >
  > 非常に多数のアイテムを持つ `QuerySet` を使用した場合、数の大きいページをリクエストした時位に、データベースによっては速度が低下する場合があります。これは、`OFFSET` 数を数えるために必要な `LIMIT`/`OFFSET` クエリの処理時間が、ページ数が増えるにつれて長くなってしまうためです。

**`per_page`**

  1ページごとに含まれる最大のアイテム数です。これには孤立したアイテム (orphan) は含まれません (詳しくは以下の `orphans` オプション引数をご覧ください)。

### Optional arguments

**`orphans`**

  最後のページに少数のアイテムだけが表示されるのを防ぎたい時に使用します。もし最後のページに `orphans` で指定した数以下のアイテムしか含まれない場合、最終ページではなく、1つ前のページにそれらのアイテムが追加されます (そのページが最終ページになります)。たとえば、23個のアイテムがあり、`per_page=10` と `orphans=3` をしていしたとします。その場合、ページ数は2になり、最初のページには10個のアイテムが、2つ目の (最後の) ページには13個のアイテムが表示されることになります。`orphans` はデフォルトで0になっているため、ページが合体することはなく、最後のページには1アイテムだけが表示されるかもしれません。

**`allow_empty_first_page`**

  最初のページがからであることを許すかどうかを指定します。もし `False` を指定し、`object_list` が空だった場合、`EmptyPage` エラーが起こります。

### メソッド

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

> **New in Django 2.0**

1から始まるインデックスをもつ [`Page`](#django.core.paginator.Page) オブジェクトを返します。このオブジェクトは、範囲外のページ数や無効なページ数もハンドリングします。

与えられた値が数字でなかった場合は、最初のページを返します。ページ数が負の数や全体のページ数より大きかった場合は、最後のページを返します。

例外 ([`EmptyPage`](#django.core.paginator.EmptyPage)) が発生するのは、`Paginator(..., allow_empty_first_page=False)` を指定して\`\`object\_list\`\` が空であるとき、かつそのときに限ります。

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

1から始まるインデックスをもつ [`Page`](#django.core.paginator.Page) オブジェクトを返します。与えられたページ数が存在しない場合、[`InvalidPage`](#django.core.paginator.InvalidPage) 例外を起こします。

### 属性

#### `Paginator.count`

すべてのページに渡るオブジェクト全体の数です。

> **Note**
>
> `object_list` に含まれるオブジェクトの数を求めるため、`Paginator` は初めに `object_list.count()` を呼びます。`object_list` が `count()` メソッドを持たなかった場合、`Paginator` は フォールバックして `len(object_list)` を使用します。これにより、Django の `QuerySet` などで、より効率のよい `count()` メソッドが利用できます。

#### `Paginator.num_pages`

トータルのページ数

#### `Paginator.page_range`

1から始まるページ数の範囲のイテレータです。たとえば、`[1, 2, 3, 4]` を生成します。

## `InvalidPage` 例外

#### `exception InvalidPage`

pagenator に無効なページ数が渡された時に発生する例外のベースクラスです。

リクエストされたページが無効な値だったり (たとえば、整数でなかったなど)、オブジェクトが1つも含まれていなかった場合、[`Paginator.page()`](#django.core.paginator.Paginator.page) メソッドは例外を起こします。一般には、`InvalidPage` 例外を捕捉すれば十分ですが、粒度を細かくしたい場合は、以下の例外のいずれかを捕捉することもできます。

#### `exception PageNotAnInteger`

整数以外の値が `page()` に与えられた時に発生します。

#### `exception EmptyPage`

`page()` には有効な値が与えられたが、そのページにオブジェクトが1つも存在しなかった時に発生します。

2つの例外は [`InvalidPage`](#django.core.paginator.InvalidPage) のサブクラスであるため、両方とも単に `except InvalidPage` と書くだけでハンドリングできます。

## `Page` オブジェクト

通常は `Page` オブジェクトを手動で作ることはありません。[`Paginator.page()`](#django.core.paginator.Paginator.page) メソッドで作成します。

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

1つのページは、`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オブジェクトでページネーションしている場合、2ページ目の [`start_index()`](#django.core.paginator.Page.start_index) は `3` を返すでしょう。

#### `Page.end_index()`

ページ上の最後のオブジェクトに対する、1から始まるインデックスを返します。これは、ページネータのリストに含まれる全オブジェクトに対するインデックスです。たとえば、5個のオブジェクトのリストを各ページ2オブジェクトでページネーションしている場合、2ページ目の [`end_index()`](#django.core.paginator.Page.end_index) は `4` を返すでしょう。

### 属性

#### `Page.object_list`

当該のページに含まれるオブジェクトのリストです。

#### `Page.number`

1から数えた現在のページのページ数です。

#### `Page.paginator`

関連する [`Paginator`](#django.core.paginator.Paginator) オブジェクトです。
