Djangoチュートリアル（ブログアプリ作成）③ - 記事一覧表示編


前回、[Django チュートリアル（ブログアプリ作成）② - model 作成、管理サイト準備編](https://qiita.com/tmasuyama/items/452c20f6014e76620b3a)では管理サイトで記事を作成するところまで確認できました。

今回は、管理サイトで作成した記事の一覧を表示できるようにしていきます。

### template 準備（ファイル作成)

最初に template を作成しましょう。
templates/blog 配下に post_list.html を作成します。

```
└── templates
    └── blog
        ├── index.html
        └── post_list.html
```

### view の準備

ここで少し重要な説明をします。

Django では**クラスベース汎用ビュー** という仕組みを使うと、簡単に model を引っ張ってきて記事を表示させたり、
テンプレートを表示させたりすることが出来、アプリ作成をグンと効率的に行うことができるようになります。
ちなみに前々回、views.py をいじったときに **generic** という表記がありました、これもクラスベース汎用ビューを使う準備として必要な宣言です。

```python:view.py
from django.views.generic import TemplateView
```

汎用クラスビューには様々な種類があり、その中でも単純に template を表示させるためだけに使われるのが
index.html の表示に使っていた **TemplateView** です。
index.html の表示のために、呼び出す template を views.py の中で指定していたことになります。

```python:view.py
class IndexView(TemplateView):
    template_name = 'blog/index.html'
```

また、これまではわかりやすいように genetic で宣言してから使うクラスを指定して import していましたが
generic.xxxView の形で呼び出すこともできるので views.py を少し書き換えてあげましょう。

```python:views.py(書き換え後)
from django.views import generic

class IndexView(genetic.TemplateView):
    template_name = 'blog/index.html'
```

これからたくさんのクラスベース汎用ビューを呼び出すことになるので、最初の宣言をスッキリとさせました。

さて、今回は template を単純に表示させるだけでなく、データベースから記事の情報モデルも呼び出してあげる必要があります。
そのため、別の **ListView** というクラスベース汎用ビューを使うのですが、使い方は TemplateView のときと似ています。

最初に使うモデルを宣言し、クラスを記述し、呼び出すモデルを指定してあげるだけです。

```python:views.py(ListViewを追加)
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 ループで展開し、それぞれの記事タイトルと日付を取り出していきます。
(各カラムのデータは、変数名にドット付きでカラム名を指定する形で取り出せます）

```html:post_list.html
<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 を編集します。

```python: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 で表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/fe2cea56-c570-8391-e1ce-6de3578bd5b8.png)

表は格好よくないですが、管理サイトから登録した記事が表示されていることが分かるかと思います。
※見た目は後で BootStrap を使って整えますが、まずは Django の基礎を理解するためにベースだけ作ってしまいます。

一つだけだと分かりづらいので、ついでに記事を 2 つぐらい、管理サイトから追加してから再度確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364501/3d215d04-9a00-887b-c071-a9332728f10f.png)
タイトルと日付がそれぞれ取り出せていることが分かりますね。

次回は、テストを自動化するユニットテストを作成していきます。

→ 次回
[Django チュートリアル（ブログアプリ作成）④ - ユニットテスト編](https://qiita.com/tmasuyama/items/cddbabbb566c00f54c89)