前回、Djangoチュートリアル(ブログアプリ作成)② - model 作成、管理サイト準備編では管理サイトで記事を作成するところまで確認できました。
今回は、管理サイトで作成した記事の一覧を表示できるようにしていきます。
template 準備(ファイル作成)
最初に template を作成しましょう。
templates/blog 配下に post_list.html を作成します。
└── templates
└── blog
├── index.html
└── post_list.html
view の準備
ここで少し重要な説明をします。
Django ではクラスベース汎用ビュー という仕組みを使うと、簡単に model を引っ張ってきて記事を表示させたり、
テンプレートを表示させたりすることが出来、アプリ作成をグンと効率的に行うことができるようになります。
ちなみに前々回、views.py をいじったときに generic という表記がありました、これもクラスベース汎用ビューを使う準備として必要な宣言です。
from django.views.generic import TemplateView
汎用クラスビューには様々な種類があり、その中でも単純に template を表示させるためだけに使われるのが
index.html の表示に使っていた TemplateView です。
index.html の表示のために、呼び出す template を views.py の中で指定していたことになります。
class IndexView(TemplateView):
template_name = 'blog/index.html'
また、これまではわかりやすいように genetic で宣言してから使うクラスを指定して import していましたが
generic.xxxView の形で呼び出すこともできるので views.py を少し書き換えてあげましょう。
from django.views import generic
class IndexView(genetic.TemplateView):
template_name = 'blog/index.html'
これからたくさんのクラスベース汎用ビューを呼び出すことになるので、最初の宣言をスッキリとさせました。
さて、今回は template を単純に表示させるだけでなく、データベースから記事の情報モデルも呼び出してあげる必要があります。
そのため、別の ListView というクラスベース汎用ビューを使うのですが、使い方は TemplateView のときと似ています。
最初に使うモデルを宣言し、クラスを記述し、呼び出すモデルを指定してあげるだけです。
from django.views import generic
from .models import Post # Postモデルをimport
class IndexView(genetic.TemplateView):
template_name = 'blog/index.html'
class PostListView(generic.ListView): # generic の ListViewクラスを継承
model = Post # 一覧表示させたいモデルを呼び出し
model = Post という記述を入れてあげることで、記事一覧が post_list という変数でリスト型として template に渡すことができます。
ここで TemplateView を使ったときのことを思い出して「templateを指定してあげるのでは?」と考えた方は鋭いです。
もちろん指定してもよいのですが、実は generic.ListView では template のファイル名をルールに沿った形にしてあげることで、明示しなくても呼び出してくれる便利機能があります。
(ただし、明示した方が第三者にとって分かりやすいので、敢えて記述する場合もあるかと思います。)
ルールとしては「post_list.html」のように、model名を小文字にしたものと、ListViewならば"list"という文字列をアンダースコアで区切った文字列をファイル名にすることです。
(使うクラスによって異なってくるため、後ほど説明します)
これで template である post_list.html を表示させ、同時に template に記事一覧を渡すための view の準備が整いました。
template 側で記事一覧の受け取り
post_list.html に渡されたモデルを受け取るには、Django ならではの記述方法があります。
Django の template では {% %} で囲むことで Python コードを記述でき、さらに html としてブラウザに値を表示させるには {{ }} と、中括弧を重ねたもので記述します。
今回、記事一覧は post_list というリスト型で変数が template で渡されているので for ループで展開し、それぞれの記事タイトルと日付を取り出していきます。
(各カラムのデータは、変数名にドット付きでカラム名を指定する形で取り出せます)
<h1>記事一覧</h1>
<table class="table">
<thead>
<tr>
<th>タイトル</th>
<th>日付</th>
</tr>
</thead>
<tbody>
{% for post in post_list %}
<tr>
<td>{{ post.title }}</td>
<td>{{ post.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
ルーティング設定
最後に記事一覧を表示させるための URL へアクセスした時に ListView を呼び出すよう、blog/urls.py を編集します。
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('post_list', views.PostListView.as_view(), name='post_list'), # ここを追加
]
今回のように、何かを表示させるときには View, Template, URL がそれぞれ絡むことを覚えておいてください。
記事一覧表示の確認
これで model を表示させる準備が整ったので runserver を実行して url にアクセスしましょう。
blogアプリの中の post_list という URL パスを先ほど設定したので、
127.0.0.1:8000/blog/post_list という URL で表示できます。
表は格好よくないですが、管理サイトから登録した記事が表示されていることが分かるかと思います。
※見た目は後で BootStrap を使って整えますが、まずは Django の基礎を理解するためにベースだけ作ってしまいます。
一つだけだと分かりづらいので、ついでに記事を2つぐらい、管理サイトから追加してから再度確認してみましょう。
次回は、テストを自動化するユニットテストを作成していきます。