Djangoの管理サイト機能を使ってみる

#はじめに
pythonを使ってマスタを作成しようと考えていたところ、Djangoを使った管理サイト機能を発見。作成したときにはまったこと等を備忘録。
SQL Server,Oracleは利用経験があったが、MySQLは初めて。


##環境
- Windows10　64bit
- Python 3.5.4
- Django 1.11.6


#Djangoを使ってWebアプリケーションを立ち上げてみる
##プロジェクト作成
Python、Anacondaのインストール方法は[こちら](https://qiita.com/usomaru/items/529b6f40902ee1eda125)の記事を参考にしてみてください。
Anacondaで新しい環境を作成し、コマンドプロンプトに以下コマンドを入力してDjangoをインストール。

```
pip install Django
```

Djangoの後ろにバージョンを指定してあげると任意のバージョンのDjangoをインストールできます。

```
pip install Django==1.10.5
```

作成したいフォルダーに移動したら、以下のコマンドを打ちます。

```
django-admin startproject 好きなプロジェクト名
```

すると、プロジェクトが作成されます。
今回はSampleという名前で作成しました。

下記のようなファイル構成になっているかと思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/8a022198-d998-e1be-5221-847caaa1cd90.png)


##Webアプリケーションを立ち上げてみる
作成したプロジェクトの```manage.py```のあるディレクトリに移動します。

移動したら以下のコマンドを実行

```
python manage.py migrate
```


以下のような反応があれば成功

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/97638b02-ca87-94e6-9597-11b631cd4046.png)


最後に以下のコマンドを実行

```
python manage.py runserver
```

Webブラウザを開いて　http://127.0.0.1:8000/
にアクセスすると、以下のようなブラウザが立ち上げるはずです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/b6c82a44-0c8b-e0a5-cd03-8ff8c84ea2c9.png)

ちなみに終了したい場合はコマンドプロンプトでCtrl+Cで終了できます。


#Pymysqlを使ってDB作成
##MySQLのインストール
[こちら](https://www.dbonline.jp/mysqlinstall/)のサイト等を参考にしました。

##pymysqlのインストール

続いてpymysqlのインストールをしていきます。
コマンドプロンプトで以下のコードを入力。

```
pip install PyMySQL
```

途中でmysql-connector-pythonも入れるように怒られたので、こちらも入れます。

```
pip install mysql-connector-python
```

##コードの編集
manage.pyにpymysqlをimportすることで、pymysqlが使えるようになります。
ので、以下のコードをmanage.pyに追加。

```python:manage.py
import pymysql

pymysql.install_as_MySQLdb()
```

続いてsettings.pyを編集します。
DBの初期設定ではsqliteへの接続となっていると思うので、MySQL用に変更します。

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '設定したDB名',
        'USER': 'DBへ接続する好きなユーザー名',
        'PASSWORD': 'DBへ接続するユーザーの好きなパスワード',
    }
}
```

##MySQLを使ってDB作成
MySQLのコマンドプロンプトを使って以下のコードを入力。

```
CREATE DATABASE 先ほどsettings.pyで設定したDB名;
```



##接続確認
コマンドプロンプトを立ち上げて、マイグレーションしてみます。

```
python manage.py migrate
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/fc1342de-e159-f01e-bc26-cfe1eb5205f1.png)


この画面がでて、以下のテーブルがMySQLのDBに追加されていればDjangoとMySQLの接続成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/9c804ad7-efff-de2b-107e-61117f0dbe97.png)

(上の画像は後で紹介するAuthUserモデルを作成してから接続したものなので、多少違うかも)


##本番環境でもMySQLを使えるようにする方法
上の操作はrunserver環境のみでの適用なので、wsi.pyに以下のコードを追加します。

```python:wsgi.py
import pymysql

pymysql.install_as_MySQLdb()
```

#管理サイト作成
##ログイン情報作成
再びコマンドプロンプトを起動し、
manage.pyの存在するディレクトリまで移動し、以下のコマンドを実行

```
python manage.py startapp accounts
```

下記のフォルダが追加されるはずです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/01831e6d-261a-f825-84fb-12f68f21e9e5.png)

accountsアプリケーションを認識してもらうために、
sampleフォルダのsetting.pyに以下のコードを追加します。

```python:setting.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts', #追加
]
```

acoountsアプリケーションのmodels.pyにAuthUserモデルを追加します。

```python:models.py
from __future__ import unicode_literals
from django.utils.encoding import python_2_unicode_compatible
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin


@python_2_unicode_compatible
class AuthUserManager(BaseUserManager):
    def create_user(self, username, email, password, last_name, first_name):
        """
        ユーザ作成

        :param username: ユーザID
        :param email: メールアドレス
        :param password: パスワード
        :param last_name: 苗字
        :param first_name: 名前
        :return: AuthUserオブジェクト
        """
        if not email:
            raise ValueError('Users must have an email')
        if not username:
            raise ValueError('Users must have an username')

        user = self.model(username=username,
                          email=email,
                          password=password,
                          last_name=last_name,
                          first_name=first_name)
        user.is_active = True
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, password, last_name, first_name):
        """
        スーパーユーザ作成

        :param username: ユーザID
        :param email: メールアドレス
        :param password: パスワード
        :param last_name: 苗字
        :param first_name: 名前
        :return: AuthUserオブジェクト
        """
        user = self.create_user(username=username,
                                email=email,
                                password=password,
                                last_name=last_name,
                                first_name=first_name)
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user


@python_2_unicode_compatible
class AuthUser(AbstractBaseUser, PermissionsMixin):
    """
    ユーザ情報を管理する
    """
    class Meta:
        verbose_name = 'ユーザ'
        verbose_name_plural = 'ユーザ'

    def get_short_name(self):
        """
        ユーザの苗字を取得する

        :return: 苗字
        """
        return self.last_name

    def get_full_name(self):
        """
        ユーザのフルネームを取得する

        :return: 苗字 + 名前
        """
        return self.last_name + self.first_name

    username = models.CharField(verbose_name='ユーザID',
                                unique=True,
                                max_length=30)
    last_name = models.CharField(verbose_name='苗字',
                                 max_length=30,
                                 default=None)
    first_name = models.CharField(verbose_name='名前',
                                  max_length=30,
                                  default=None)
    email = models.EmailField(verbose_name='メールアドレス',
                              null=True,
                              default=None)
    date_joined = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(verbose_name='有効フラグ',
                                    default=True)
    is_staff = models.BooleanField(verbose_name='管理サイトアクセス権限',
                                   default=False)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email', 'last_name', 'first_name']
    objects = AuthUserManager()

    def __str__(self):
        return self.last_name + ' ' + self.first_name
```
settings.pyに作成したAuthUserモデルを反映させます。

```python:settings.py
AUTH_USER_MODEL = 'accounts.AuthUser'
```

##実行準備
実行準備をしていきます。

まず、コマンドプロンプトを立ち上げて以下のコードを入力します。
マイグレーションです。

```
python manage.py makemigrations
```

もし、もうすでにmakemigrationsやmigrateを実行している場合、マイグレーションをするとエラーとなることがあるそうです。
私はなりました。
特に問題なければ一度DBのテーブルを全て削除した状態でマイグレーションを実行すると、できます。

続いてコマンドプロンプトからログインユーザーを作成します。
以下のコードを実行

```
python manage.py createsuperuser
```

すると、以下のような感じでコマンド上で登録ができるはずです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/8932fde0-2ffe-79d5-a185-e4da683eab01.png)

一度パスワード間違えたみたいで怒られてしまいました…



##ログインしてみる
サーバーを起動してログインしましょう。

```
python manage.py runserver
```

http://localhost:8000/admin/
にアクセス

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/09a4714a-6104-fd83-7fc6-3a2cf301018e.png)

↓

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201826/82fc86a3-bf07-e96f-6a8d-a3b0cda5c0f6.png)


ログインできました。

##日本語にしたい…
ってときは、settings.pyを少しいじると日本語になります。

```python:settings.py
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

この管理サイトいろいろと他にもできるのですが、制限も多く存在するみたいですね。
([こちら](https://qiita.com/tag1216/items/20a618bb7b2b59455bc0)のサイトさん参照)


#参考サイト
- [DjangoでWebアプリケーションを構築する](https://codelab.website/django-webapp/)

- [Python3系でDjangoでMySQLに接続する](https://codelab.website/python3-django-mysql/)
- [Djangoでログイン認証できるようになるまで](https://codelab.website/django-login/)

- [Djangoで管理サイトを作成する](https://codelab.website/django-admin/)

- [Djangoの管理サイトに過度な期待をしてはいけない](https://qiita.com/tag1216/items/20a618bb7b2b59455bc0)