Djangoでモデルを定義する（基礎の基礎２）

#1 やること
今回は、<a href = "https://qiita.com/ykoji/items/ab8eb64f3903b0d7c1f2">前回</a>行ったDjango初期設定＋Helloworldで作った超基礎的なウェブアプリケーションに、データベースを構築していきたいと思います。まず、models.pyでデータベースのフォーマットを設定し、管理者モードでデータベースにサンプルデータを作成します。そして、そのデータを呼び出してテンプレートのHTMLファイルを使ってレンダリングし、表示させるところまでをやってみます。（以下の内容の利用・実行は自己責任でお願いします。）

#2 モデルの設定（models.py)

<a href = "https://docs.djangoproject.com/ja/3.2/intro/overview/">Djangoの公式レファレンスのModelの解説ページ</a>にあるサンプルコードを参考にしてModel(models.py)を作ってみます。この解説ページにモデル作成における必要なことは全て書かれていると思いますので、余裕があれば、よく読んでみてください。

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

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

    def __str__(self):
        return self.full_name


class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

    def __str__(self):
        return self.headline
```

#3 管理者の設定と、サンプルデータの作成

管理者サイトで操作できるように、todo/admin.pyを以下のように編集して、モデルを登録します。

```python:admin.py
from django.contrib import admin
from .models import Reporter, Article

admin.site.register(Reporter)
admin.site.register(Article)
```

Modelを設定したら、makemigrationとmigrateを実行します。

```terminal
(virtual) firstapp % python3 manage.py makemigrations
Migrations for 'todo':
  todo/migrations/0001_initial.py
    - Create model Reporter
    - Create model Article
    
(virtual) firstapp % python3 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, todo
Running migrations:
  Applying todo.0001_initial... OK
```

管理者を設定します。(createsuperuserコマンドで以下のように設定します。----のところは各自の環境によります。）

```
(virtual) firstapp % python3 manage.py createsuperuser
Username (leave blank to use '----'):     
Email address: -----
Password: 
Password (again): 
Superuser created successfully.
```
Runserverをして127.0.0.1:8000/admin/にアクセスをします。管理者名、設定したパスワードでログインをすると、モデルが反映されているはずなので、サンプルデータを作ってみます。例えば、以下のようなデータを適当につくってSaveします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280313/fb9281e6-f0a2-ebc0-60df-cb7351ab9b5e.png)

# 4.サンプルデータを呼び出し、レンダリングして出力
ウェブサイトの見た目を作るプログラムは、views.pyに記述します。前回作成したプログラムにmodeltestという新しい関数を定義します。objectをすべて取得する場合には、object.all()を使います。（ここで特定のobjectを選択的に取り出したい場合には、object_pickup = Article.objects.get(headline='---')といった形で抽出することもできます。）

```python:views.py
from django.http.response import HttpResponseNotAllowed
from django.shortcuts import render
from .models import Reporter, Article

def hello(request):
    hw = 'Hello World!'
    return render(request, 'base.html', {'object':hw})

def modeltest(request):
    object_list = Article.objects.all()
    return render(request, 'modeltest.html', {'object_list':object_list})
```

modeltest.htmlを次のように編集します。forループがhtmlで使えるようになるのはウェブアプリケーションの醍醐味です。

```html:modeltest.html
object_list:{{object_list}}

{% for item in object_list %}
  <li>item:{{item}}</li>
  <li>item.pub_date:{{item.pub_date}}</li>
  <li>item.headline:{{item.headline}}</li>
  <li>item.content:{{item.content}}</li>
  <li>item.reporter:{{item.reporter}} </li>
{% endfor %}

```
todo/urls.pyについて、modeltestにアクセスした時に、views.pyのmodeltest関数が呼び出されるよう、以下の通り編集します。

```python:urls.py
from django.urls import path
from .views import hello, modeltest

urlpatterns = [
    path('hello/', hello, name='hello'),
    path('modeltest/', modeltest, name = 'modeltest'),
]

```

これで準備が整いました！
127.0.0.1:8000/modeltest/にアクセスすると、以下のウェブサイトが表示されます。先ほど管理者サイトで作成したデータが呼び出されて表示されることが確認できます。

```website
<QuerySet [<Article: テスト>]>
item:テスト
item.pub_date:July 25, 2021
item.headline:テスト
item.content:これはテストです。
item.reporter:投稿者１
```