Djangoを始めよう！ 〜チュートリアル②〜

# 概要

[前回](http://qiita.com/gcfuji/items/bff55a0b8ae1b76c0ca1)の続きです。
今回のチュートリアルでは以下の項目を実施したいと思います。

- データベースのセットアップ
- モデルの作成
- Djangoが提供してくれる、管理サイトの活用

# データベースの設定

データベースの設定は、mysite/settings.pyで行います。

```py3
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
```

上記がDBの設定箇所となります。
今回はMySQLを想定していますので、ローカル環境でMySQLのDBサーバを立ち上げて、接続してみます。

以下の様な設定となります。

```py3
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'dbname',  # 適当です
        'USER': 'dbuser',  # 適当です
        'PASSWORD': 'FIXME',  # 適当です
        'HOST': 'FIXME',  # 適当です (ローカルホストなら空でも可)
        'PORT': 'FIXME',  # 適当です (デフォルトポートなら空でも可)
    }
}
```

次に、PythonでMySQLを利用する為のモジュールをpipでインストールします。

```shell-session
$ pip install PyMySQL
```

最後に、DjangoのプロジェクトにMySQLを利用する事を宣言します。
デフォルトではsqliteになっているので、manage.pyに以下の記述を行いましょう。

```py3:mysite/manage.py
import pymysql
pymysql.install_as_MySQLdb()
```

ここまででrunserverします。

```shell-session
$ python manage.py runserver
```

以下の結果がでれば、正常に接続できています。
(migrate系のエラーが全て消えている事も確認して下さい。)

```shell-session
[t.fujimoto@tfujimoto-MacBook-Air:mysite]$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
October 12, 2016 - 12:51:50
Django version 1.10.2, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```

# settings.pyの中身

データベースの設定など、プロジェクト全体の設定を行う、settings.pyですが、様々な重要な設定が書かれています。

中でも、INSTALLED_APPSはかなり重要です。
INSTALLED_APPSはこのプロジェクトのDjangoインスタンスの中で有効化されているすべてのDjangoアプリケーションの名前を保持しています。

アプリは複数のプロジェクトによって使用される事ができますし、また、他の開発者が作ったアプリを導入する事ができます。

初期では以下の様な設定になっています。

```py3:mysite/mysite/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```

各アプリは以下の様な役割を担います。

- django.contrib.admin
	- 管理サイトアプリ
- django.contrib.auth
	- 認証アプリ
- django.contrib.contenttypes
	- コンテンツタイプフレームワーク
- django.contrib.sessions
	- セッションフレームワーク
- django.contrib.messages
	- メッセージフレームワーク
- django.contrib.staticfiles
	- 静的ファイルの管理フレームワーク

Webアプリケーションとして、よく使われるアプリがデフォルトで付いてくるイメージです。

上記のアプリケーションたちは、データベースを使います。
その為に、初期設定として、テーブルを作成しなければなりません。

下記のコマンドで、migrateファイルを実行してくれます。

```shell-session
$ python manage.py migrate
```

# モデルを作成する

モデルは、手持ちのデータに対する唯一の決定的なソースです。
モデルには、自分が格納したいデータにとって、必要なフィールドと、そのデータの挙動を記載します。

今回のチュートリアルでは投票アプリを制作していますので、
投票項目が格納されている、Questionテーブル(モデル)と、Questionの投票項目のテキストなどを格納するChoiceテーブル(モデル)を作成します。

以下の様になります。

```py3:mysite/polls/models.py
from django.db import models

# Create your models here.


class Question(models.Model):
    quesion_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)
```

# モデルを有効にする

モデルは作成できましたが、まだデータベースには反映されていません。

- CREATE TABLE
- QuestionやChoiceオブジェクトにPythonからアクセスする為のデータベースAIPの作成

上記を可能にする為の設定を行います。

まずは、Djangoプロジェクトにpollsアプリケーションを利用する事を明記しなければなりません。

先ほど紹介した、mysite/settings.pyのINSTALLED_APPSを以下の記述に変更します。

```py3:mysite/mysite/settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig',  # 追加
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
```

上記の追加ができたら、マイグレーションスクリプトを作成します。
以下のコマンドでマイグレーションスクリプトが作成できます。

```shell-session
$ python manage.py makemigrations polls
```

makemigrationsを実行することで、Djangoのモデルに変更があった事を伝え、そして変更をマイグレーションの形で保存できます。

マイグレーションとは、Djangoがモデルの変更をディスク上のファイルに保存する方法です。
作成されたマイグレーションは各アプリケーションのmigrationsディレクトリに番号で格納されます。

今回作成した、マイグレーションスクリプトは以下の様になります。

```shell-session
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-12 13:20
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Choice',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('choice_text', models.CharField(max_length=200)),
                ('votes', models.IntegerField(default=0)),
            ],
        ),
        migrations.CreateModel(
            name='Question',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('quesion_text', models.CharField(max_length=200)),
                ('pub_date', models.DateTimeField(verbose_name='date published')),
            ],
        ),
        migrations.AddField(
            model_name='choice',
            name='question',
            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Question'),
        ),
    ]
```

マイグレーションスクリプトが作成できたら、あとは実行するだけです。

```shell-session
$ python manage.py migrate
```

上記で、まだ実行されていないマイグレーションスクリプトを実行してくれます。

また、マイグレーションスクリプトを指定して、どの様なSQLが発行されるかを確認する事も可能です。

```shell-session
$ python manage.py sqlmigrate polls 0001
```

以下で、0001のファイルであれば、CRATE文などが確認できると思います。

## モデル作成からマイグレーションスクリプト実行までの流れ

モデル作成(各アプリのmodels.py)
↓
プロジェクトにアプリケーション読み込み(mysiteのsettings.pyのINSTALLED_APP)
↓
モデルを元にマイグレーションスクリプトを作成(makemigrations)
↓
マイグレーションスクリプトを実行(migrate)

# Djangoの設計哲学

Djangoアプリケーションは「プラガブル」です。
アプリケーションは特定のDjangoプロジェクトに結びついていないので、アプリケーションを複数のプロジェクトで利用したり、単体で配布したりできます。

# Django Admin

Djangoでは管理サイトがデフォルトで付いてきます。
まずは、管理サイトにログインできるスーパーユーザーを作成します。

```shell-session
$ python manage.py createsuperuser
```

対話形式でユーザーIDやパスワードを設定していって下さい。

スーパーユーザーができたら、実際にログインしてみます。

ブラウザを起動して、ローカルドメインの```localhost/admin/```にアクセスします。

ログインに成功すれば、以下の様な管理画面が表示されます。


![スクリーンショット 2016-10-12 23.16.56.png](https://qiita-image-store.s3.amazonaws.com/0/129216/39e2cffe-f196-a4fa-a458-caecb76a214f.png)


## Pollsアプリをadmin上で編集できる様に設定する。

何も設定していなければ,Pollsアプリはadminでは表示されていません。
Pollsアプリもadminから操作できる様に修正します。

pollsのadmin.pyを以下の様に修正します。

```py3:polls/admin.py
from django.contrib import admin

# Register your models here.

from .models import Question

admin.site.register(Question)

```

これで再度開発サーバをリロードすると、

![スクリーンショット 2016-10-12 23.21.20.png](https://qiita-image-store.s3.amazonaws.com/0/129216/3bfbd91d-cce5-e115-5d11-31c840be9ec9.png)


無事、POLLSが追加されている事がわかると思います。

これで、GUI操作でPOLLSが修正できる様になりました。

# まとめ

今回は、モデルの作成、マイグレーションスクリプトの実行、管理画面の見方について説明しました。

地味な回にはなりましたが、次回以降のビュー操作と密接に絡む重要な回でした。

次回は、自作のビューの作成やテンプレートファイルの使い方について解説していきたいと思います。

[GitHub](https://github.com/gcfuji/django_tutorial/tree/tutorail-2)

# シリーズ

- [Djangoを始めよう！ 〜チュートリアル①〜](http://qiita.com/gcfuji/items/bff55a0b8ae1b76c0ca1)
- [Djangoを始めよう！ 〜チュートリアル②〜](http://qiita.com/gcfuji/items/27d2c9e4b3334447b6af)
- [Djangoを始めよう！ 〜チュートリアル③〜](http://qiita.com/gcfuji/items/c8a0e4add7a628c12f8d)
- [Djangoを始めよう！ 〜チュートリアル④〜](http://qiita.com/gcfuji/items/68101227141cde134326)
- [Djangoを始めよう！ 〜チュートリアル⑤〜](http://qiita.com/gcfuji/items/1b6079bec064a4e8b211)
- [Djangoを始めよう！ 〜チュートリアル⑥〜](http://qiita.com/gcfuji/items/8560eade5a11c08a0ff1)