Green Screen

【このサイト制作記】ページネーション(前へ次へのリンク)

戻る

修正課題
今更気づいた。
トップページの投稿一覧、3件までしか表示できない、選べない…

というわけで、ページネーションをつけましたとさ。

画像

?ページネーション、とは、

よくウェブサイトについている、
「次へ 1 2 3 ... 前へ」
みたいなリンク。あれのこと。
コンテンツが大量になった時に、一度にすべて読み込むと
サイトが劇的に重くなったりスクロールが苦痛になったり、
いろいろ問題になるので、ページわけして数件ずつ表示しよう、
という機能。

ここから先の方法はWEBサイト制作用の「Django」フレームワークでの実装方法
(自分向け備忘録)なので、関係ない人はそっとお戻りください。
ーーーーーーーーーーーーーーーーーーーーー

1)views.pyにimport追加
from django.core.paginator import Paginator

2)記事一覧取得メソッドに以下記述する

#記事一覧を取得(全件取得にする)
posts = Post.objects.all().order_by('-updated_dt')

#paginatorを構築し、指定ページを取得
paginator = Paginator(posts, article_per_page); #pagenator生成。対象モデルと1ページあたり件数
page_number = request.GET.get('page') #サイトのrequestからページNoを取得(?page=2など)
page_obj = paginator.get_page(page_number) #指定されたページNoのPageを取得

#Webサイトへ返すのはもとのモデルではなく、Pageオブジェクト
return render(request, 'greenscreen/post_list.html', {'posts': page_obj}) #page_objを渡す

※page_numberが無効の時はデフォルト(普通は1ページ)が自動表示される。親切!
 タイプミスによるエラーや、悪意のある「異空間URLへのジャンプ」の試みが防止される。
 
3)template(htmlファイル側)

元が直接モデルを使用していたので、Pageに合わせて変更
{% for post in posts %}
   ↓
{% for post in page_obj.object_list %}
※object_listの中身がもともとのpostと同値なので、残りのロジックは書き換えしないでOK


4)template(htmlファイル側)ページ選択用のリンク一覧を作る
 hrefの中の「?page=xx」に反応して、自動的にview.py側の「request.GET.get('page')」
 にページ番号が入るという。

<div class="pagenation">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}">前へ</a>
{% else %}
<span class="disabled">前へ</span>
{% endif %}

{% for num in page_obj.paginator.page_range %}
{%if page_obj.number == num %}
<span class="current-page">{{ num }}</span>
{% else %}
<a href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}

{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">次へ</a>
{% else %}
<span class="disabled">次へ</span>
{% endif %}
</div>


5)1件分の記事詳細から「戻る」リンクで戻った時に、元のページに戻るための設定
<h2><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title|truncatechars:30 }}</a></h2>

<h2><a href="{% url 'post_detail' pk=post.pk %}?page={{ page_obj.number }}">{{ post.title|truncatechars:30 }}</a></h2>

6)views.pyに戻って、post_detailを変更
original_page_number = request.GET.get('page')

を追加し、元のpostと一緒にrenderへ返す。

context = {
'post': post,
'original_page_number' : original_page_number
}
return render(request, 'greenscreen/post_detail.html', context)

7)最後に、記事1件表示用のhtmlファイルの記述を修正
<a href="{% url 'post_list' %}">戻る</a>
↓↓↓

{% if original_page_number %}
<a href="{% url 'post_list' %}?page={{ original_page_number }}">戻る</a>
{% else %}
<a href="{% url 'post_list' %}">戻る</a>
{% endif %}

ーーーーーーーーーーーーーーーーーーーーー
(余談)
最近は、ついつい生成AIのGEMINIに何でも聞いてしまう。
本当は本家サイトのドキュメントが一番いいんだけどな。
と思って出典どこって質問したらそれも出してくれた。

https://docs.djangoproject.com/en/5.0/topics/pagination/

後で見返すと、確かにこの内容に沿って作っていた。
生成AIのすぐれものな点は、今回の僕みたいに
「えっと、ホームページについてる次へとか前へっていうリンク、あれ作りたいんだけど?」
な状態の人にもナビゲーションできるところかな。
いったん「ページネーション」というキーワードさえ知れば、
従来通りの資料探しでもうまくいくんだけどね。

作成日: 2025年7月8日22:57

更新日: 2025年7月11日20:03

タグ

このサイト制作記 Django

戻る