TemplateViewを使ってみよう！IndexView編

#DB（データベース）の中身を一覧表示しよう！
目標はListViewというテンプレートビューを用いて、データベース上のデータをリスト表示することです。
開発現場ではそんなの1時間でできるよ！？と怒られたことも(-_-;)

しかし、今回もdjango使いたての方向けにやさし目に書き上げております。

ListViewの使い方としては例えば掲示板アプリ、お店の一覧などで用いられます。
Amazonの商品一覧ページのようなものだって作れるようになりますよ！

##IndexViewのおさえるべき特徴について
面倒なビューの記述がなくなります。
かなり簡単に表示が可能なため、練習にうってつけであることも言えます。
また、仮のページ作成ができるので、素早くwebサイトの開発が可能です。
覚えて損はありません！

##今回のファイル構成

```
mysite
│  db.sqlite3
│  manage.py
├─mysite
│  │  settings.py
│  │  urls.py
└─test_app
    │  admin.py(ここをadmin画面設定のために編集)
    │  apps.py
    │  models.py(ここをモデル定義のために編集)
    │  tests.py
    │  urls.py(ここもルーティング設定のために編集)
    │  views.py(ここもIndexView設定のために編集)
    ├─migrations
    ├─templates
    　  └─test_app
    　       └─list.html(ここもページ上にリスト表示させるため編集)
```

##新規モデルの作成
モデル定義ファイル、models.pyを編集して行きます。
**モデルとは、DBのテーブルを定義するファイルです。**
まずはmodels.pyの編集に移ってからなれるのがおすすめです。
後でモデルとは何なのかわかってきます。

このモデルを作成することを、テーブルを切る、とも開発現場では表現されます。

models.pyの編集は以下の通りとなります。

```models.py
from django.db import models

# Create your models here.
class Shop(models.Model):
    #各フィールドの定義
    name = models.CharField('shopname',max_length=30)
    tell_num = models.CharField('tell_number',max_length=13)
    address = models.CharField('address',max_length=30)
    created_at = models.DateTimeField(auto_now_add=True)

    #admin画面の表示内容
    def __str__(self):
        return self.name
```
modelsをインポートしているところについてですが、modelsとはなんなのかいまだに私もわかりません。あまり意識すべきところではないため慣れて覚えておく必要があります。
ただし、ここから言えることはShopというクラス定義を行い、models.Modelを継承していることがわかります。
継承することにより、モデルとして各フィールドの定義を行うことができます。

文字列を入れたい場合は`models.CharField`、日付を入れたい場合は`models.DateTimeField`を用います。数字を入れたい場合は`models.IntegerField`を用いるため、忘れたら思い出す感覚で結構です！

モデル定義ができたら、このコマンドを入力してみましょう！

```terminal
$python manage.py makemigrations

Migrations for 'test_app':
  test_app\migrations\0001_initial.py
    - Create model Shop
```
ずらずらっと何か出てきましたね。
`- Create model Shop`が表示されていたら成功です！

続いて、マイグレートを行います。
DBはモデル定義の変更履歴を差分で取っています。
models.pyの変更のたびにこのコマンドを2つセットで入力することをお忘れないようにお願いします。

それでは、マイグレート（移行）！

```terminal 
$python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, test_app
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK
  Applying test_app.0001_initial... OK
```
この`... OK`がすべて表示されていたら、成功です！

続いては作成モデルの確認をadmin管理画面で行っていきます。

##adminスーパーユーザーの作成
初めてadmin管理画面にログインする際、ここで**admin管理画面にログインするためのユーザーアカウントが必要となります。**
createsuperuserで最高権限のユーザーを作成してみましょう！最初のadmin管理画面にログインするために必要です。

```
$python manage.py createsuperuser
```
ユーザー名とパスワード、emailadressを入力します。

```
$python manage.py createsuperuser
Username (leave blank to use 'user'):
```

ユーザー名はブランクでEnterをたたくとデフォルトであるuserが設定されます。
お好きな名前を入力しましょう。

```
$python manage.py createsuperuser
Username (leave blank to use 'user'):
Email address:
Password:
Password (again):
Superuser created successfully.
```
次々とメアド、パスワードの入力が要求されます。
パスワードのみ二回確認、空欄不可なので注意しましょう。

すべて打ち終えたら、現在作成したユーザーとパスワードを用いて、ログインしてみましょう！

##admin管理画面で作成モデルの確認
今回使用されているDBはsqlite3です。
これはDjangoに標準インストールされているDBなので、このままで作業を進めましょう。
ここでは先ほどのモデルの作成状況を見てみることが目標です。

![無題6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/f3840b5e-8767-9012-a8b6-a59ad68cecfb.png)


あれれ、作成したDBテーブルが表示されていません。💦
**これは、作成テーブルをadmin.pyに登録していないことが原因です。**
admin.pyに登録してみましょう。

```admin.py
from django.contrib import admin
from .models import Shop

# ここにモデル名を含め書き足す
admin.site.register(Shop)
```
admin管理画面にログインすると、
(補足)ログインURLは

```
http://localhost:8000/admin
```
![無題7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/bd79577c-40ab-3040-ec72-53a6a6161e05.png)

モデルの追加がされています。

仮にデータを挿入してみましょう！
追加方法はこのように行います。
ADD SHOPを押す
![無題9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/345aef69-61b7-a5fc-ea90-8546ace7b6b0.png)

店の名前、電話番号、住所を入れる
![無題10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/3f867070-8aea-f649-4c3f-a70d9446155d.png)
SAVEで保存OK！
![無題11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/58f3afae-ab2a-480c-6e36-9da2546e1cb6.png)

それでは。ルーティング設定に参ります！

##ルーティングをurls.pyで設定
URLに/indexと打つと、リスト画面が表示されるようにすることが目標。

```urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('index/',views.IndexView.as_view(),name='index'),
]
```
views.pyではテンプレートビューである`ListView`を継承したビュークラスを定義します。
`as_view()`を付けることにより、ビューとしてdjangoに認識されます。テンプレートビューを用いる場合は必要であるといった程度で覚えてください。

それでは、viewの設定です。

##リスト表示用のIndexViewをviews.pyで設定
TemplateViewを用いたviews.pyでの設定はかなりシンプルです。
それはモデルを指定することとテンプレートを指定することです。
ListViewを継承することで、めっちゃ簡単に設定することができます。

以下のテンプレートの指定について、2通りの設定が考えられます。
templateを指定する場合は、templates/test_app/list.htmlとなっているファイルに対し、以下のように`template_name`で指定します。

```テンプレートを指定しているviews.py
from django.views import generic
from .models import Shop

# Create your views here.
class IndexView(generic.ListView):
    model = Shop
    template_name = 'test_app/list.html'　#IndexViewの中に指定
```

templateファイル名を指定しない場合はモデル名\_list.htmlと書き方が決まっているため、この後に注意しましょう。
具体的に、**test_app_list.htmlといった指定になります。**

```テンプレートを指定しないviews.py
from django.views import generic
from .models import Shop

# Create your views here.
class IndexView(generic.ListView):
    model = Shop
```

ちなみに、`template_name`を指定してもモデル名_list.htmlのhtmlファイルがあるか探してくれます。djangoは優秀、て思ってみましょうかね？

##ページ表示のためのhtmlファイルの設定
```list.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
  <p>一覧の表示</p>
  <table>
    <tr>
      <th>店名</th>
      <th>電話番号</th>
      <th>住所</th>
      <th>ページ作成日</th>
    </tr>

    {% for shop in shop_list %}#ここに注目！
    <tr>
      <td>{{ shop.name }}</td>
      <td>{{ shop.tell_num  }}</td>
      <td>{{ shop.address  }}</td>
      <td>{{ shop.created_at }}</td>
    </tr>
    {% endfor %}
  </table>
  </body>
</html>
```
モデル名\_listと変数を書くと、モデルデータの一覧が取得できます。ここはルールなので覚えるところです。
for文で一つ一つ取得し、`.name`などとモデルのカラム名を指定し、表形式で表示を行っております。
カラム名は忘れますので、models.pyで確認を行ってください！
それでは、サーバーを起動し、

```
$python manage.py runserver
```

```
http://localhost:8000/index
```
で表示を確認してみましょう！
![無題12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547305/f7a5a76e-fc04-d9c6-dff5-391c986e7cd7.png)

表示が確認できない場合は、エラーをググったり、怪しい設定部分を確認してみましょう。
すべて正しく設定できれば表示されます。**自分を信じてあきらめないでください！！**

##最後に
今回はTemplateViewを用いたリスト表示の書き方についてのまとめでした。
この手順を覚えられればかなり応用がきいたり、バックエンドの設定が大まかにわかってきます。中級者へ突破するための第一ステップとなるところになりそうなので、取り上げてみました！

それでは、一緒に頑張ってゆきましょう！
続きは[TemplateViewをつかってみよう！Detailview編](https://qiita.com/flee-style/items/a8ec6929e798ffd9f0e2)