【Django】PyCharmを使ってDjangoの開発環境構築〜User認証と管理画面まで作ります〜

# Djangoを使ってwebアプリケーションを作ろう

pythonを使ったwebフレームワークの中でも人気が高いDjango。
しかし日本語のドキュメントが少なかったり書籍も充実していなかったりで、
本格的な開発をしたくてもなかなかハードルが高いのが実情です。

ディレクトリ構成やデフォルトのUser, admin機能などDjango独特の
「クセ」もあるので、慣れるまで正直結構大変だと思います。

そこでこの記事では、自分としても早く慣れたいので数をこなしていく為に
開発の準備部分にあたる「開発環境構築」を備忘録として残していきます。
自分の為の記事という側面が強いので、説明が足りない部分があったり
逆に多すぎたりすることがあると思いますが、ご容赦ください。


# スペック
macOS Mojave ver.10.14.2
PyCharm ver.2018.2.4
Python 3.7.1
Django 2.1.5

# では早速始めます。
自分の好きな場所にまずディレクトリを作ります。
今回は自分の5番目のプロジェクトなのでproject5という名前で作ります。

```console
$ mkdir project5
$ cd project5
```

# 仮想環境を作る
Djangoのドキュメントを見ていると、プロジェクトごとに仮想環境を作って
仮想環境で開発していることが多い印象があります。
プロジェクトごとにPythonやPythonパッケージを管理できるメリットがあるようです。

仮想環境を作らずローカル環境で生の状態で開発を行う場合、
PythonはPython2系とPython3系で使うコマンドが異なります。
例えばターミナルからローカルサーバーを立ち上げる際、
Python2系だと 

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

ですが、Python3系だと

```console
$ python3 manage.py runserver
```

としなければなりません。
それだけかと思いますが、仮想環境だとPython3でも

```console
$ python manage.py runserver
```
で通るので楽だし、余計なエラーに悩まされずに済みます。

## では仮想環境を作っていきます
先ほど作ったディレクトリにいながら次のコマンドを打ち込みます。

```console
$ python3 -m venv venv
$ source venv/bin/activate
```

これで仮想環境が有効化されました。

```console
(venv) jibunnoMacBook-puro:project5 jibun$ 
```

先頭に`(venv)` がついていたら仮想環境にいますよ、ということ。
ここから先は全て仮想環境上で作業を進めていきます。

# Djangoをインストール
```console
$ pip install Django

Collecting Django
  Using cached https://files.pythonhosted.org/packages/36/50/078a42b4e9bedb94efd3e0278c0eb71650ed9672cdc91bd5542953bec17f/Django-2.1.5-py3-none-any.whl
Collecting pytz (from Django)
  Using cached https://files.pythonhosted.org/packages/61/28/1d3920e4d1d50b19bc5d24398a7cd85cc7b9a75a490570d5a30c57622d34/pytz-2018.9-py2.py3-none-any.whl
Installing collected packages: pytz, Django
Successfully installed Django-2.1.5 pytz-2018.9
You are using pip version 10.0.1, however version 18.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command
```

Djangoが入りました。
最後の2行でpipのupgradeを促されていますが、
この先何かエラーが起きたらupgradeすることにして一旦進みます。
ちなみに`pip` はPythonを便利に利用する為のパッケージを管理するツールです。

# PyCharmのインストール
[PyCharm](https://www.jetbrains.com/pycharm/)はチェコのJetBrains社が開発した、Pythonの為の統合開発環境ソフトです。
有料、無料とありますが無料でも困らないくらい機能が充実しています。
`pip install` をコンソールからだけでなくGUIででき、
初心者にも優しい仕様だと個人的には思っています。
私は以前からインストール済なので申し訳ないですが
インストール方法についてはここでは省略します^^;

# PyCharmのターミナルで進めます
さて、既にプロジェクトを開始する為のディレクトリは作成済みなので、
PyCharmのスタート画面では`open` を選択します。
<img width="773" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/d311f714-fd58-982d-13c9-9c23aea36b51.png">

先程mkdirしたディレクトリを選択し、画面が立ち上がります。
<img width="1407" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/1940eb68-935f-db81-d5f7-5d197c6ee864.png">

ここから先は、私はPyCharmのターミナルをして進めていきます。
デフォルトのターミナルが好きな方はそれでやっていただいても構わないです。
左下の`Python Console` `Terminal` `TODO`から`Terminal` を選択。

```console
(venv) jibunnoMacBook-puro:project5 jibun$
```

この状態がセットされていると思われます。
されていなければ、仮想環境に入ってプロジェクトディレクトリに移動してください。

# cookiecutterのインストール

次にcookiecutterをpipを使ってインストールします。
せっかくPyCharmのターミナルを使える状態にしたので、ターミナルを使ってインストール
しても良いのですがここは一旦GUIで初心者にも優しいインストール方法を試します。

<img width="716" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/6f9b0512-8663-2581-1ca2-31fc42d3f927.png">

まずはメニューバーの`PyCharm`を選択

<img width="192" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/47adc707-62ec-8ef8-63d2-b31a137da0de.png">
次に`Preferences...` を選択

<img width="1006" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/3765ac71-e649-497e-0e29-eb13676bd11d.png">

`Project: プロジェクト名`を選択=>`Project Interpreter` を選択

<img width="1007" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/dc8cd086-634d-5c5e-3da2-405e06a3a245.png">

下の方に地味に選択されているプラスボタンを選択。
検索窓が出ますので、「cookiecutter」を入力して検索してみましょう。
左下の`Install Package` を選択するとインストールが開始されます。

<img width="918" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/0f51061c-d74c-4668-5ed7-621c0883cd94.png">

`installed successfully`が現れたらインストール成功です。
<img width="906" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/bd830834-28a5-fe52-2b95-562abc884638.png">

バツボタンで閉じて結構です。

# cookiecutterとは
Djangoのディレクトリ構成は独特の性質があります。
具体的には、最初にmkdirで作った大元のディレクトリの直下に、
[プロジェクト]ディレクトリ(一つ)と[アプリケーション]ディレクトリ(複数可)を
同列に配置し、[プロジェクト]ディレクトリで各[アプリケーション]ディレクトリを
管理していくようなイメージになります。
ruby on railsのように`rails g...`で定型のディレクトリが
自動的に生成されるのとは異なって、Djangoはこれをある程度自分の手で
構築していかなければならず、さらに複雑なディレクトリ階層を一つ間違えただけで
プログラムは動いてくれなくなります。

cookiecutterは20個ほどの質問に回答するだけで（まあまあ多い）、
プロジェクトの雛形を生成してくれます。
慣れないうちはcookiecutterを使った方が早く開発の中身に取りかかれると思います。

cookiecutterの雛形はいくつかgithubに公開されていますが、
`全部乗せ` のようなメニューが以下のコマンドで実現できます。

```console 
$ cookiecutter https://github.com/pydanny/cookiecutter-django
```

```console
You've downloaded /Users/higashiyama/.cookiecutters/cookiecutter-django before. Is it okay to delete and re-download it? [yes]: yes
project_name [My Awesome Project]: project5
project_slug [project5]: 
description [Behold My Awesome Project!]: 
author_name [Daniel Roy Greenfeld]: hiroshimaeasyryo
domain_name [example.com]: 
email [hiroshimaeasyryo@example.com]: 
version [0.1.0]: 
Select open_source_license:
1 - MIT
2 - BSD
3 - GPLv3
4 - Apache Software License 2.0
5 - Not open source
Choose from 1, 2, 3, 4, 5 (1, 2, 3, 4, 5) [1]: 
timezone [UTC]: Asia/Tokyo
windows [n]: n
use_pycharm [n]: y
use_docker [n]: n
Select postgresql_version:
1 - 10.5
2 - 10.4
3 - 10.3
4 - 10.2
5 - 10.1
6 - 9.6
7 - 9.5
8 - 9.4
9 - 9.3
Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 (1, 2, 3, 4, 5, 6, 7, 8, 9) [1]: 
Select js_task_runner:
1 - None
2 - Gulp
Choose from 1, 2 (1, 2) [1]: 
custom_bootstrap_compilation [n]: 
use_compressor [n]: 
use_celery [n]: 
use_mailhog [n]: 
use_sentry [n]: 
use_whitenoise [n]: 
use_heroku [n]: n
use_travisci [n]: 
keep_local_envs_in_vcs [y]: 
debug [n]: 
 [INFO]: .env(s) are only utilized when Docker Compose and/or Heroku support is enabled so keeping them does not make sense given your current setup.
 [SUCCESS]: Project initialized, keep up the good work!
```

たくさん聞かれますが、全部Enter押してデフォルト設定のままでも通ります。
今回は`project_name` と`author_name` と`windows` と`timezone` だけ真面目に回答しました。
慣れてきたらこの質問の中身をしっかりと理解して自分の思い通りカスタマイズできるように
なっていきたいですね。

<img width="206" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/e43ae8e6-fce9-c8b5-7da5-e4f85113c59a.png">

ディレクトリをこのように自動で生成してくれています。

# ここから先はこのやり方が正攻法かわからないです
### まずは、当たって砕けてみます
本来ならここでサーバー立ち上げるとすんなり先に進める、
という内容のドキュメントが多いですが、進まないですね。

```console
$ python manage.py runserver
...
ModuleNotFoundError: No module named 'environ'
```

`django-environ` をインストールするとこのエラーは解消します。
<img width="917" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/d67b93b9-1589-32b3-94ab-dcbb68e7d4eb.png">

この状態から`python manage.py runserver` を実行すると、次のエラーが現れます。

```console
ModuleNotFoundError: No module named 'crispy_forms'
```

次は`crispy_forms` が足りないらしいです。
コンソールでもpreferenceからインストールしても良いのでインストールします。

<img width="409" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/8b4752bf-3da0-9b7a-e77f-8ba927c2a955.png">
名前に気をつけてください。
もう何度かこんな感じが続きますが、一応やってみましょう、
`python manage.py runserver`

```console
ModuleNotFoundError: No module named 'allauth'
```

次にインストールするのはこれです、`allauth`

<img width="398" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/81348118-b1f7-35e3-8383-d373da3251b9.png">

名前に注意しないといけないことも慣れてきた感があります。

```console
ModuleNotFoundError: No module named 'rest_framework'
```

次はこれだそうです。
果てしなさそうな感じがしますが、そのうち終わるので安心してください。

<img width="401" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/25157e03-69e6-4a3c-b4a0-abd27368e6c9.png">

(省略)

この先似たような感じを繰り返していくので省略して必要なものだけ掲載します。

```console
ModuleNotFoundError: No module named 'debug_toolbar'
ModuleNotFoundError: No module named 'django_extensions'
django.core.exceptions.ImproperlyConfigured: Error loading psycopg2 module: No module named 'psycopg2'
```

# デフォルトのデータベースからMySQLへ変更する

postgresqlをデフォルトのSQLとしていることに絡み、
以下のエラーが発生します。

```console
django.db.utils.OperationalError: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```
そもそもpostgresqlではなくMySQlを使いたかったので、
これを変更していきます。

まずはこれまでと同じように`PyMySQL` をインストール。
`manage.py` のimport文直後に、

```python 
import pymysql


pymysql.install_as_MySQLdb()
``` 

を挿入。
`/config/settings/base.py` の中の
DATABASES = 以下を次のように変更します

```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '[DB_name]', # DB名を設定
        'USER': 'root', # DBへ接続するユーザIDを設定
        'PASSWORD': '', # DBへ接続するユーザIDのパスワードを設定
        'HOST': 'localhost',
        'PORT': '8889',
        'OPTIONS': {
            'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
        },
        'TEST': {
            'NAME': 'test_sample'
        }
    }
}
```

続いてMySQLにつなぎ、データベースを作成します

```console
$ mysql -u root
mysql> CREATE DATABASE db_pr5;
Query OK, 1 row affected (0.07 sec)

mysql> USE db_pr5
Database changed
```

そして、マイグレーションを実行しDjangoとMySQLが接続できているか確認します。
一旦control+Dでmysqlを抜けてください

```console
$ python manage.py migrate

...

Operations to perform:
  Apply all migrations: account, admin, auth, contenttypes, sessions, sites, socialaccount, users
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... 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 users.0001_initial... OK
  Applying account.0001_initial... OK
  Applying account.0002_email_max_length... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK
  Applying sites.0003_set_site_domain_and_name... OK
  Applying socialaccount.0001_initial... OK
  Applying socialaccount.0002_token_max_lengths... OK
  Applying socialaccount.0003_extra_data_default_dict... OK
```

# いよいよサーバーを立ち上げます

```console
$ python manage.py runserver

...

January 21, 2019 - 07:17:04
Django version 2.1.5, using settings 'config.settings.local'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

```

<img width="780" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/c8150148-8f44-af2a-7ca7-9e4e02ccc4e3.png">

project5が立ち上がりました。

<img width="783" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/2199045a-8194-48ce-e0ab-a88bcc2ad995.png">

<img width="775" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/3ad2c5d0-b5e0-8e8e-e4ee-a6362b141d95.png">

<img width="782" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265778/65d91e4d-68f4-679d-8d1d-39027d1e5b61.png">

認証周りと管理画面を一気にセッティングできました。