「Djangoで始めるブログ作成講座」の第四回です。
前回はブログにコメント投稿機能を実装し、管理画面のカスタマイズも同時に行いましたね。
「Djangoで始めるブログ作成講座」の第三回です。 前回はDjangoで画像を扱い、ブログのアイキャッチ画像を定義しました。 [sitecard subtitle=関連記事 url=https://freemas.stepupka[…]
前回の内容が多めだったので、今日は小休止で短めです。
投稿の一覧ページにページング(ページ送り)機能を実装していきましょう!
この記事を読んで取り組むことで、Djangoの以下の基本的な使い方を習得することができます。
- Djangoのクラスベースビューでのページング実装方法
- Templateへのページングの書き方
- DjangoにおけるCSSでのページングデザインの調整
- ページングの表示、非表示の仕方
Djangoで始めるブログ作成講座④:ページング機能を導入しよう!
ページング機能の実装はViewとTemplateの2つを修正するだけで完成します。
それぞれを見ていきましょう。
ページング設定をViewに加える
1 2 3 4 5 6 |
class PostListView(ListView): model = Post template_name = 'post_list.html' context_object_name = 'posts' ordering = '-id' paginate_by = 5 #追加 |
「pagenate_by」のところに数字を適用すれば、その数字の数だけデータを表示して、それ以降は別ページに自動で送ってくれます。
別のプログラミング言語や、同じDjangoでも関数ベースでViewを作成していると記述量がもっと増えるので、クラスベースビューの強みが発揮されている場面ですね。
ページング表示をTemplateに加える
続いてTemplateにもページングを適用させます。
今後のことを考えて、実装はblog_base.htmlに行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
-- 省略 -- <main class="container mb-4"> <div class="row"> <div class="col-md-8 mt-4"> {% block content %} {% endblock %} {% block pagination %} <div class="pagination justify-content-center"> <!-- 前ページを表示 --> {% if page_obj.has_previous %} <a class="page-link" href="?page=1">« First</a> <a class="page-link" href="?page={{ page_obj.previous_page_number }}">‹ Prev</a> {% else %} <span class="page-link disabled">« First</span> <span class="page-link disabled">‹ Prev</span> {% endif %} <!-- 現在のページの前後を表示 --> {% for num in page_obj.paginator.page_range %} {% if page_obj.number == num %} <span class="page-link current-page">{{ num }}</span> {% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %} <a class="page-link" href="?page={{ num }}">{{ num }}</a> {% endif %} {% endfor %} <!-- 次ページを表示 --> {% if page_obj.has_next %} <a class="page-link" href="?page={{ page_obj.next_page_number }}">Next ›</a> <a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last »</a> {% else %} <span class="page-link disabled">Next ›</span> <span class="page-link disabled">Last »</span> {% endif %} </div> {% endblock %} </div> </main> |
上のコードを見ると記述量が多くてうんざりするかもしれませんが、していることは単純です。
最初のページと前ページの2つを表示します。
それぞれを
- 先頭のページに居る場合
- それ以外
で分けています。最初がそれ以外で、次が先頭ページに居る場合ですね。
ページングはURLに「?page=1」のような文言を末尾に付けることで移動が可能になります。
前ページの番号は「page_obj.previous_page_number」でアクセス可能です。
現在のページならば、ページの番号をそのまま表示し、そうでないならば前後のページ番号を表示しています。
今回はpage_obj.numberに3や-3を加えているので、現在のページから前後2ページの数字が表示されることになります。
例えば5ページ目に居る場合は、ページングの表記は以下のようになります。
前後2ページに移動できますし、先頭に戻りたい場合は「<<First」をクリックすればいいと感覚的に分かりますね。
前ページと全く同じ構成になっていることが分かると思います。
ページング表示の準備ができました。
表示が気に入らない場合はCSSで変更を
ページングはbootstrapでデザインしていますが、気に入らない場合は変更することも可能です。
今回のブログでは、専用のCSSを既に定義しているので、プロジェクトのstaticsフォルダにある「css/blog.css」ファイルに追記しています。
1 2 3 4 5 6 7 8 |
.pagination .disabled,.pagination .current-page { color: #000; } .pagination .disabled:hover,.pagination .current-page:hover { color: #000; background-color: #fff; } |
ページングが不要なページに対策する
さて、今回はblog_base.htmlにページング機能を実装しましたが、このままでは記事詳細画面にもページングが表示されてしまいます。
表示したくないページに対する対策を行っていきましょう。
post_detail.htmlを開いて、以下の一文を追加してください。
1 2 3 4 5 6 7 8 9 10 |
<form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit" class="btn btn-primary">Post</button> </form> </div> </div> </div> {% block pagination %}{% endblock %} <!-- 追加 --> {% endblock %} |
block paginationの中に何も記載しないことで、blog_base.htmlの記述を上書きできます。
これで詳細画面にはページネーションを表示しない実装が出来ました。
ページングを確認してみる
投稿のデータをいくつか登録して開発環境にアクセスし、ページングが正常に機能するか見てみましょう。
もしも多数のデータを作るのが大変ならば、Viewsのpagenate_byの数字を減らすことで表示件数を減らせるので、ページの数を増やすことができます。
おわりに
クラスベースビューを使っていると記述量は減る傾向にあるのですが、ページングに関しては「たったこれだけの記述でいいのか!?」と驚いたことを覚えています。
私がクラスベースビューを進める理由はいくつかありますが、このページング機能はそのうちの一つですね。
さて、今回もここまでのソースをGithubに掲載しておくので、もしも見返したい場合は確認してみてください。
次回はブログにカテゴリーを実装していきましょう。
今回の記事は小休止として少なめの内容でしたが、次の記事では新しい内容が多く出てきます。
「Djangoで始めるブログ作成講座」の第五回です。 前回はDjangoでページング機能を実装しました。 [sitecard subtitle=関連記事 url=https://freemas.stepupkaraoke.com/p[…]