Progateで作ったWebアプリをDjangoで作ってみる！ Part4 -Read編-

ProgateのNode.jsコースではお買い物リストアプリを作るのですが、これと全く同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

**目標物**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/16123e6f-f050-226e-a369-8383267de571.png)


HTMLとCSS、PNG形式画像は使い回しで、一部をDjango用のタグに変えます。

#前回のおさらい

[Part3](https://qiita.com/insilicomab/items/bf2b983c1433cffe63f0)

Part3ではデータベースの設定をしました。

今回はデータベースに登録されているお買い物アイテム一覧が表示されるListページを作成していきます。

#Listページの作成

はじめに**urls.py**ファイルにコードを追加していきます。

URLパターンを逆引きできるように、``app_name = 'list'``と名前をつけます（☆1）。

[URLconf に名前空間を追加する](https://docs.djangoproject.com/ja/3.2/intro/tutorial03/#namespacing-url-names)

```python:listapp/list/urls.py
from django.urls import path
from .views import ListTop, ListIndex

# URLパターンを逆引きできるように名前をつける
app_name = 'list' # ☆1

urlpatterns = [

    # リクエストされたパス部分が''に合致した場合、views.pyのListTopクラスをインスタンス化する
    path('', ListTop.as_view(), name='top'),
]
```

ListページのHTMLファイル（index.html）を作っていきます。

Part2でやったように静的ファイルを読み込むためのタグを挿入、変更します（☆2）。

ProgateのNode.jsコースで作ったもの（ejsファイル）を流用しているので一部変なタグがありますが、次回以降で修正していきます。

Listページのindex.htmlに書かれている``{% %}``や``{{ }}``はテンプレートと呼ばれるもので、``{% %}``は「**処理**」を行うもので``{{ }}``は「**データ**」を扱うものです。

☆3の``href="{% url 'list:top' %}``の記載について見てみます。まずこのタグはurlが呼び出されるものです。じゃあ、どのようなurlが呼び出されるかというと、``'list'``は**urls.py**の``app_name``で指定した**list**アプリのことで、``'top'``は**urls.py**の``name='top'``と定義したコードに対応したurlです。つまり、この場合だと、<font color="Tomato">**list**</font>アプリのtop.htmlが呼び出されることになります。

☆4の``{% for object in object_list %}``は**object_list**から一つずつ取り出す繰り返し処理です。**object_list**はListViewで指定したモデルの全データを示していて、今回の場合だとListModelの中の全てのデータが格納されています。つまり、買い物リストです。

``{% for object in object_list %}``と``{% endfor %}``タグで囲まれま部分がループ処理となります。

``{{ forloop.counter }}``はループした回数を表示、つまり、リストの上から順に1, 2, 3,...というふうになります。

``{{ object.item }}``は``object_list``から取り出された個別のデータの中のitemフィールドを意味しています。この場合だと、買い物リストです。


```html:index.html
{% load static %} <!--☆2-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>LIST APP</title>
    <link rel="stylesheet" href="{% static 'list/style.css' %}"> <!--☆2-->
  </head>
  <body>
    <header>
      <a href="{% url 'list:top' %}" class="header-logo">LIST APP</a>　<!--☆3-->
    </header>
    <div class="container">
      <div class="container-header">　
        <h1>買い物リスト</h1>
        <a href="/new" class="new-button">+ 新規登録</a>
      </div>
      <div class="index-table-wrapper">
        <div class="table-head">
          <span class="id-column">ID</span>
          <span>買うもの</span>
        </div>
        <ul class="table-body">
          {% for object in object_list %}　<!--☆4-->
            <li>
              <div class="item-data">
                <span class="id-column">{{ forloop.counter }}</span>　<!--☆4-->
                <span class="name-column">{{ object.item }}</span>　<!--☆4-->
              </div>
              <div class="item-menu">
                <form action="/delete/<%= item.id %>" method="post">
                  <input type="submit" value="削除">
                </form>
                <a href="/edit/<%= item.id %>">編集</a>
              </div>
            </li>
          {% endfor %}　<!--☆4-->
        </ul>
      </div>
    </div>
  </body>
</html>
```

**views.py**ファイルにコードを追加していきます。

**ListView**という、Djangoがあらかじめ用意しているclassに書かれている関数や変数を使えるようにします。**ListView**は、データベースのデータを取り出して表示するイメージのものです。文字どおり、リストにする感じです。

**ListView**をインポートして、それを継承した``ListIndex``を作成し、``template_name``を定義します（☆5）。

**model.py**ファイルの中のどのデータベースを使うか指定していきます。**models.py**の**ListModel**を使うため、まずは``from .models import ListModel``でimportして、``ListIndex``の中で``model = ListModel``と設定します（☆6）。

```python:listapp/list/views.py
from django.shortcuts import render
from django.views.generic import TemplateView, ListView # ☆5
from .models import ListModel # ☆6

class ListTop(TemplateView):
    # top.htmlをレンダリング
    template_name = 'list/top.html'

class ListIndex(ListView):  # ☆5
    # index.htmlをレンダリング
    template_name = 'list/index.html'
    model = ListModel # ☆6
```

**urls.py**ファイルにコードを追加して、**views.py**の**ListTop**クラスを読み込むようにします（☆7）。

```python:listapp/list/urls.py
from django.urls import path
from .views import ListTop, ListIndex

# URLパターンを逆引きできるように名前をつける
app_name = 'list'

urlpatterns = [

    # リクエストされたパス部分が''に合致した場合、views.pyのListTopクラスをインスタンス化する
    path('', ListTop.as_view(), name='top'),

    # リクエストされたパス部分が'index'に合致した場合、views.pyのListIndexクラスをインスタンス化する
    path('index/', ListIndex.as_view(), name='index'), # ☆7
]
```

最後にTopページのListページへのリンク用のタグも変更しておきます（☆8）。

```html:top.html
{% load static %}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>LIST APP</title>
    <link rel="stylesheet" href="{% static 'list/style.css' %}">
  </head>
  <body>
    <div class="top-wrapper">
      <div class="top-detail">
        <h2 class="subtitle">買い物リストアプリ</h2>
        <h1 class="title">LIST APP</h1>
        <p class="description">
          LIST APPは、買い物をリストアップするサービスです。
          <br>
          買いたいものをリストに登録してみましょう。
        </p>
        <a href="{% url 'list:index' %}" class="index-button">一覧を見る</a> <!--☆8-->
      </div>
      <div class="top-image">
        <img src="{% static 'list/top.png' %}">
      </div>
    </div>
  </body>
</html>
```

これでお買い物リストが表示される一覧ページ（仮）ができあがりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/2879d0d3-bab4-eadb-2955-f4c7935e2ffe.png)


ちゃんとデータベースに登録したアイテムがリストに表示されています！

つぎは、リストに追加していくためのページを作っていきます！

Part5に続きます！

[Part5](https://qiita.com/insilicomab/items/2fed2ab28abb538a9683)