こんばんはエンジニアの眠れない夜です。
今回の記事はDjangoのGeneric.ListViewでページネーションの実装ってどうやるんだろう?簡単にできるかな?と思っている方が対象です。
結論から言うとかなり簡単にできるので気楽に読み進めてくださいね。
【Django】ページネーション用にViewの設定
まずはページネーションさせたいViewのクラスでGenericListViewを継承します。
paginate_by
に1ページに表示させたいmodel
の数を設定します。ここでは20にしました。
今回モデルは適当にPage
としています。
from django.views import generic
class ListView(generic.ListView):
template_name = "app/list.html"
model = Page
paginate_by = 20
ページネーションさせるためのViewの設定はたったこれだけです。Djangoは後ろでよく働いてくれますね!
※ template_name
の設定は”app/list.html”としていますが、ここは自分の環境に合わせて設定してください。
【Django】ページネーションのためのurls.pyの設定
設定は至ってシンプルです。いつもどおりListViewの設定をするだけです。
path('list/', ListView.as_view(), name='list'),
至って普通すぎて説明することもありません。
【Django】ページネーションのためのテンプレートの設定(Bootstrap)
Viewの設定とURLの設定ができたのであとは見え方(テンプレート)を調整するだけです。
Bootstrapを使っている人向けにコピペでできるコードを用意しました。
ページネーションを表示したい場所に貼り付けてください。
ベースはNarito Blogさんのものを使わせていただきました。
ページ数が多いとページ番号が画面からはみ出して表示されてしまったので、現在のページ±5に制限しています。
↓この部分
{% if num <= page_obj.number|add:5 and num >= page_obj.number|add:-5 %}
省略
{% endif %}
それからページネーションのGETでパラメーターを渡す方法を`/`から`?page=`に変更しています。
ページネーションを使い回す設定
ページネーションしたいリストページが複数あると、毎回上のコードをコピペするのは美しいコードとは言えません。
pagination.html
でページネーション部分を保存して、挿入したい部分に {% include 'APP_NAME/pagination.html'%}
を書くと使い回しもできて、コードもスッキリして最高です。
まとめ
やることはたったの2つです。
paginate_by = 20
をViewに設定する。- テンプレートに上のコードをコピペする。
簡単すぎてミスる余地がありません。
Bootstrap用のテンプレートの設定だったのでBootstrapを使っていない方は少し見た目の調整が必要かもしれませんが、とても簡単にページネーションの設定ができましたね。
何より嬉しいのはView側での設定がたったのpaginate_by = 20
だけで済んでしまうことです。
もっとごりごり設定をしたい方は、テンプレートでpage_obj
を通じていろんな値を取得できるのでいろいろ試してみてください。
今回のテンプレートで使っている変数をまとめると
- page_obj.previous_page_number 前のページ番号
- page_obj.next_page_number 次のページ番号
- page_obj.has_previous 前のページがあるか
- page_obj.has_next 次のページがあるか
- page_obj.paginator.page_range 表示可能なページ番号一覧(型:リスト)
こんな感じです。これだけの情報があればページネーションも独自のカスタマイズも簡単にできますね。
それでは素敵なDjangoライフを(^^)v
この方法ではページ遷移がうまくいきません。ほかのページが用意されていないような状態になります。何か抜けていませんか?
酒居酒居さん
コメントありがとうございます!
近日中に確認致します。
しばらくお時間をいただければと思います。
どうぞよろしくお願い致します。
酒居酒居さん
確認が遅くなり申し訳ございません。
テンプレート側の設定を改良して、urls.pyの設定も重複部分をなくしました。
以前より内容がシンプルになっているのでもう一度読み返してお試しください。
ご参考になれば幸いです。
[…] 【Django】Generic.ListViewでページネーション(ページ送り)する方法 […]