diadia

興味があることをやってみる。自分のメモを残しておきます。

django ページネーションについて(改訂版)

ページネーションについて

ページネーションは一覧表示させるオブジェクトを1ページ内にどれだけ分割して表示させるか。それに関わる技術のことのようだ。

関連ドキュメント

ページネーション | Django ドキュメント | Django

メモ

djangoにおけるページネーションに関わるオブジェクトは2つある。

  1. Paginator オブジェクト
  2. Page オブジェクト

このオブジェクトの役割は具体的にはなんなのか?
Paginator オブジェクトはどんなページネーションにするかを定めるために使うのと、そのオブジェクトを使ってページを表示することができる(もちろん他にも)。
Page オブジェクトはあるページに該当するデータを参照したり、その隣(前のページや後のページ)が存在するか、その隣のページを参照するような役割をもつ。

1ページ当たりいくつのオブジェクトを描画するかを定めるのがPaginatorの役割で、それはsettings.pyでページネーションを定めるのではなくviewsの各ロジックに組み込んで使用する。 またPageオブジェクトはフロントエンド側で使いやすいと思われる。具体的には隣のページがあればページを繰るアイコンを表示させるとかクリックすることで該当ページの内容を表示させるとか。 もちろんPageオブジェクトをテンプレートで使いたいのでviewsでPageオブジェクトを生成しcontextに格納することを想定される。両オブジェクトはともにviewsで使用されることか2つのオブジェクトを組み合わせた関数を作ってしまうと便利かも。

以前の記事

ページネーションの必要素は2要素のようだ。表示するべきリストオブジェクトの作成とのページを繰る関係のオブジェクトである。で前者はPageクラスインスタンスにobject_list属性で表現できるようだ。

ページネーション | Django ドキュメント | Django

後者については同じくPageクラスインスタンスに属性やメソッド使ったりすると表現できるようだ 。

ページネーション | Django ドキュメント | Django

page_obj.object_listは普段object_listをhtml上に表現するように扱えばいいので特に問題はないだろう。page_obj.numberについて考える。まずpage_obj.numberはどこに使うか?という問題である。言うまでもなくviews.pyのrequest.GETに関するコードの流れの最終着地点はcontextに追加し、render関数を介してhtml上に表示させることだ。だからpage_obj.numberはhtmlに表現される。htmlの下部の"前へ","1","2","3","次へ"というものだ。page_obj.numberはここに使われる。またpage_objには以下のメソッドがある。これらを使うと前へ、とか"3"を表現できるようになりそうだ。

Page オブジェクトメソッド 動作
page_obj.has_next() 次のページが存在する時Trueを返す。
page_obj.has_previous() 前のページが存在する時Trueを返す。
page_obj.has__other_pages() 次のページまたは前のページが存在する時Trueを返す。
page_obj.has_next_number() 次のページ数を返す。次のページが存在しない場合はInvalidPage例外を起こす。
page_obj.start_index() ページ上の最初のオブジェクトに対する、1から始まるインデックスを返します。これは、ページネータのリストに含まれる全オブジェクトに対するインデックスです。たとえば、5個のオブジェクトのリストを各ページ2オブジェクトでページネーションしている場合、2ページ目の start_index() は 3 を返すでしょう。
page_obj.end_index() ページ上の最後のオブジェクトに対する、1から始まるインデックスを返します。これは、ページネータのリストに含まれる全オブジェクトに対するインデックスです。たとえば、5個のオブジェクトのリストを各ページ2オブジェクトでページネーションしている場合、2ページ目の end_index() は 4 を返すでしょう。

だからhtmlではpage_obj.object_listの使い方としては、

{% for obj in page_obj.object_list %}

{{ obj }}

{% endfor %}

ページを繰る関係で言えばhtmlでは以下のように表現できる。

{%for n in  page_obj.paginator.page_range %}

<a href="?page={{ n }}">{{ n }}</a>

{% endfor %}

page_objの作り方

page_objはPageクラスのインスタンスである。しかしながらpage_obj=Page()と作るわけではないようだ。作り方はpage_obj = pagenator_obj.page(number)で作る。pagenator_obj=Pagenator()で作成する。