ページネーションLink to this heading
Django はページネーションしたデータの管理を助けるクラスを提供しています。つまり、データをいくつかのページに分割して、「戻る/次へ」リンクを使って移動できるようにします。これらのクラスは django/core/paginator.py で実装されています。
カスタマイズ例Link to this heading
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
Paginator をビューで使用するLink to this heading
次は、ビューの中で queryset をページネーションするために 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:
{% 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">« 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 »</a>
{% endif %}
</span>
</div>
Paginator オブジェクトLink to this heading
Paginator には次のようなコンストラクタがあります。
- class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)Link to this definition
Required argumentsLink to this heading
object_listリスト、タプル、
QuerySet、あるいはその他のスライス可能なオブジェクトで、count()または__len__()を実装しているオブジェクトを指定します。一貫性のあるページネーションのためには、QuerySetは並び替えられていなければなりません。たとえば、order_by()句を使用したり、モデルでデフォルトのorderingを指定します。per_page1ページごとに含まれる最大のアイテム数です。これには孤立したアイテム (orphan) は含まれません (詳しくは以下の
orphansオプション引数をご覧ください)。
Optional argumentsLink to this heading
orphans最後のページに少数のアイテムだけが表示されるのを防ぎたい時に使用します。もし最後のページに
orphansで指定した数以下のアイテムしか含まれない場合、最終ページではなく、1つ前のページにそれらのアイテムが追加されます (そのページが最終ページになります)。たとえば、23個のアイテムがあり、per_page=10とorphans=3をしていしたとします。その場合、ページ数は2になり、最初のページには10個のアイテムが、2つ目の (最後の) ページには13個のアイテムが表示されることになります。orphansはデフォルトで0になっているため、ページが合体することはなく、最後のページには1アイテムだけが表示されるかもしれません。allow_empty_first_page最初のページがからであることを許すかどうかを指定します。もし
Falseを指定し、object_listが空だった場合、EmptyPageエラーが起こります。
メソッドLink to this heading
- Paginator.get_page(number)Link to this definition
-
1から始まるインデックスをもつ
Pageオブジェクトを返します。このオブジェクトは、範囲外のページ数や無効なページ数もハンドリングします。与えられた値が数字でなかった場合は、最初のページを返します。ページ数が負の数や全体のページ数より大きかった場合は、最後のページを返します。
例外 (
EmptyPage) が発生するのは、Paginator(..., allow_empty_first_page=False)を指定して``object_list`` が空であるとき、かつそのときに限ります。
- Paginator.page(number)Link to this definition
1から始まるインデックスをもつ
Pageオブジェクトを返します。与えられたページ数が存在しない場合、InvalidPage例外を起こします。
属性Link to this heading
- Paginator.countLink to this definition
すべてのページに渡るオブジェクト全体の数です。
- Paginator.num_pagesLink to this definition
トータルのページ数
- Paginator.page_rangeLink to this definition
1から始まるページ数の範囲のイテレータです。たとえば、
[1, 2, 3, 4]を生成します。
InvalidPage 例外Link to this heading
- exception InvalidPageLink to this definition
pagenator に無効なページ数が渡された時に発生する例外のベースクラスです。
リクエストされたページが無効な値だったり (たとえば、整数でなかったなど)、オブジェクトが1つも含まれていなかった場合、Paginator.page() メソッドは例外を起こします。一般には、InvalidPage 例外を捕捉すれば十分ですが、粒度を細かくしたい場合は、以下の例外のいずれかを捕捉することもできます。
- exception PageNotAnIntegerLink to this definition
整数以外の値が
page()に与えられた時に発生します。
- exception EmptyPageLink to this definition
page()には有効な値が与えられたが、そのページにオブジェクトが1つも存在しなかった時に発生します。
2つの例外は InvalidPage のサブクラスであるため、両方とも単に except InvalidPage と書くだけでハンドリングできます。
Page オブジェクトLink to this heading
通常は Page オブジェクトを手動で作ることはありません。Paginator.page() メソッドで作成します。
- class Page(object_list, number, paginator)Link to this definition
1つのページは、
len()を使ったり直接イテレーションした時、Page.object_listのシーケンスのように振る舞います。
メソッドLink to this heading
- Page.has_next()Link to this definition
次のページが存在する時、
Trueを返します。
- Page.has_previous()Link to this definition
前のページが存在する時、
Trueを返します。
- Page.has_other_pages()Link to this definition
次のページ または 前のページがが存在する時、
Trueを返します。
- Page.next_page_number()Link to this definition
次のページ数を返します。次のページが存在しないときは
InvalidPage例外を起こします。
- Page.previous_page_number()Link to this definition
前のページ数を返します。前のページが存在しないときは
InvalidPage例外を起こします。
- Page.start_index()Link to this definition
ページ上の最初のオブジェクトに対する、1から始まるインデックスを返します。これは、ページネータのリストに含まれる全オブジェクトに対するインデックスです。たとえば、5個のオブジェクトのリストを各ページ2オブジェクトでページネーションしている場合、2ページ目の
start_index()は3を返すでしょう。
- Page.end_index()Link to this definition
ページ上の最後のオブジェクトに対する、1から始まるインデックスを返します。これは、ページネータのリストに含まれる全オブジェクトに対するインデックスです。たとえば、5個のオブジェクトのリストを各ページ2オブジェクトでページネーションしている場合、2ページ目の
end_index()は4を返すでしょう。
属性Link to this heading
- Page.object_listLink to this definition
当該のページに含まれるオブジェクトのリストです。
- Page.numberLink to this definition
1から数えた現在のページのページ数です。
- Page.paginatorLink to this definition
関連する
Paginatorオブジェクトです。