ゼロから始めるDjango(part:2)

# 前回
[ゼロから始めるDjango\(part:1\) \- Qiita](https://qiita.com/taninao1122/items/1ec0de78307ecd89432a)

# 参考文献
[はじめての Django アプリ作成、その2 \| Django ドキュメント \| Django](https://docs.djangoproject.com/ja/3.1/intro/tutorial02/)

# DataBaseの設定
## mysite/setting.py
- jangoの設定をいろいろ書いてあるPythonモジュール
- データベースのサポートなどもデフォルトで入っている

### INSTALLED_APPS
アプリケーションの重要部分の設定。詳細は以下
- `django.contrib.admin` - 管理（admin）サイト
- `django.contrib.auth` - 認証システム
- `django.contrib.contenttypes` - コンテンツタイプフレームワーク
- `django.contrib.sessions` - セッションフレームワーク
- `django.contrib.messages` - メッセージフレームワーク
- `django.contrib.staticfiles` - 静的ファイルの管理フレームワーク

### テーブルの作成
データベースのテーブル作成は以下のコマンドで行う。

```
python manage.py migrate
```
-`migrateコマンド`は上記のINSTALLED_APPSの設定を参照し`mysite/setting.py'ファイルのデータベース設定に従って必要なすべてのデータベースを作成する。
- コマンドラインクライアントでテーブルの中身を表示することが可能
    -  \dt (PostgreSQL
    -  SHOW TABLES; (MySQL)
    -  .schema (SQLite)
    -  SELECT TABLE_NAME FROM USER_TABLES; (Oracle)


## データベースモデルを生成
```
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
```
- QuestionとChoiceのモデル二つを生成している
- どちらもmodelsクラスのサブクラス
- 個々のクラスはモデルのデータベースフィールを表現している

- CharFiledやIntegerFieldなどでどのようなデータ型を記憶させるかを指定している
- `models.CharField(max_length=200)`や`models.IntegerField(default=0)`のように条件や初期値も指定可能
- ForeignKey(外部キー)で`Question`とリレーションシップを定義している。

## アプリケーションをプロジェクトに反映
- アプリケーションをプロジェクトに含めるには`setting.py'の`INSTALLED_APPS`に設定を追加する
- アプリケーション(今回はPolls)内の`apps.py`内に記載されているクラスを`INSTALLED_APPS`に設定する

```
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```
## モデルの変更を反映させる
下記コードを実行するとDjangoに変更があったことをマイグレーションの形で保存する

```
python manage.py makemigrations polls
```
* マイグレーション:Djangoがモデル(データベーススキーマ)の変更を保存する方法。

-----

```
 python manage.py check 
```
プロジェクトに問題がないかを確認するコマンド

-----

モデルのテーブルを作成したら、migrateを再度実行しモデルのテーブルをデータベースに作成する

## モデルの変更を実施する3ステップ

- モデルを変更する
- マイグレーション作成のためにpython manage.py makemigrationsを実行
- データベースにこれらの変更を適用するためpython manage.py migrateを実行

## マイグレーションの作成と適用のコマンドが分かれているのはなぜ？
- マイグレーションをバリデーション管理システムにコミットしアプリとともに配布するため
- 開発の容易化
- ほかの開発者や本番環境にとって使いやすいものになるため

# データベースAPIの利便性の向上
シェル内で`>>> Question.objects.all()`とすると
以下のように出力される。
`<QuerySet [<Question: Question object (1)>]>`
これだとデータベースのテーブルがどうなっているかわからない

そのため`__str__'メソッドをQuestionとChoiceの両方に追加する

```
from django.db import models

class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text
```

- シェルでの表示の利便性以外にもdjangoの自動生成adminのオブジェクトの表現として使用される
- そのため__str__()メソッドをモデルに追加することは重要

```polls/models.py

from django.db import models
from django.utils import timezone


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
```
# 管理ユーザを作成する

```
python manage.py createsuperuser
```

# admin上で編集可能にする

```
from django.contrib import admin

from .models import Question

admin.site.register(Question)
```