【Python/Django】よく使うコマンドのまとめ(1) <仮想環境、プロジェクト、アプリケーションの作成>

#### 背景
Python/Djangoで開発をすすめるにあたり、よく使うコマンドをまとめておきます。

先人たちの知恵をお借りするなどして解決できたことを、この場をお借りして感謝するとともに、大変恐縮ですが自分のメモとしても、こちらへまとめておきます。

#### 環境
（本番環境）

- AWS EC2 (Amazon Linux 2)
- Python 3.7.9　　　　※2020/12/10時点のAmazon Linux2でのデフォルト
- Django 3.1.3
- PostgreSQL 11.5　　※同上
- Nginx 1.12　　　　　※同上
- Gunicorn
- Putty 0.74


（開発環境）

- Windwos 10 Pro
- Python 3.9.0
- Django 3.1.3
- PostgreSQL 13.1
- Nginx 1.19.5
- Gunicorn
- Putty 0.74


## 0. 仮想環境の作成

仮想環境を作りたいディレクトリの直下へ移動したのちに、下記を実行します。
Python 3.x系で開発する際は、先頭は「python3」とすることが必須です。

```:ターミナル
$ python3 -m venv venv_＜プロジェクト名＞
```

## 1. django-adminコマンド

### 1-1. Djangoプロジェクトの自動作成

```:ターミナル
$ django-admin startproject ＜プロジェクト名＞
```

## 2. manage.pyコマンド

manage.pyコマンドは、Python仮想環境に入り、`manage.py` の存在するディレクトリ内で行ないます。

仮想環境に入る

- 開発環境

```:ターミナル
$ cd ＜venv_プロジェクト名＞\Scripts
$ activate.bat

(venv_＜プロジェクト名＞)$
```

- 本番環境

```:ターミナル
$ source ~/venv_＜プロジェクト名＞/bin/activate

(venv_＜プロジェクト名＞)$
```

- 共通

manage.pyがあるディレクトリに移動する

```:ターミナル
(venv_＜プロジェクト名＞)$ cd ~/venv_＜プロジェクト名＞/＜プロジェクト名＞
```

仮想環境から抜ける

```:ターミナル
(venv_＜プロジェクト名＞)$ deactivate
```


### 2-1. Djangoアプリケーションの自動作成

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py startapp ＜アプリケーション名＞
```

上記1-1.および2-1.を行なうことにより、下記ディレクトリ構成となります。

```:ファイル構成
プロジェクト名                    1-1.で作成される
　┣━　プロジェクト名              〃
　┃　　　┣━　__init__.py         〃
　┃　　　┣━　settings.py         〃　
　┃　　　┣━　urls.py             〃
　┃　　　┗━　wsgi.py             〃
　┣━　manage.py                 〃
　┗━　アプリケーション名           2-1.で作成される
　　　　　┣━　migrations          〃
　　　　　┃　　　┗━　__init__.py  〃
　　　　　┣━　__init__.py         〃
　　　　　┣━　admin.py            〃
　　　　　┣━　apps.py             〃
　　　　　┣━　models.py           〃
　　　　　┣━　tests.py            〃
　　　　　┗━　views.py            〃
```

なお、WEBアプリケーション作成後のファイル構成は、以下の通りです。
コマンドで自動作成されないディレクトリやファイル（下記「**」印）は、自身で作成します。
下記は、ミニマム構成としてアプリケーションが１つの例を挙げています。

```:ファイル構成
プロジェクト名                      プロジェクト全体をまとめるディレクトリ
　┣━　プロジェクト名                プロジェクト全体に関わるファイルとまとめるディレクトリ
　┃　　　┣━　__init__.py           Pythonのパッケージであることを示すファイル
　┃　　　┣━　settings.py           プロジェクト設定ファイル
　┃　　　┣━　urls.py               プロジェクト用ルーティング定義ファイル
　┃　　　┗━　wsgi.py               デプロイ用ファイル
　┣━　manage.py                   コマンド実行用ファイル
　┗━　アプリケーション名             アプリケーション関連ファイルをまとめるディレクトリ
　　　　　┣━　migrations            マイグレーションファイルを格納するディレクトリ
　　　　　┃　　　┗━　__init__.py    Pythonのパッケージであることを示すファイル
　　　　　┣━　templates             テンプレートファイルを格納するディレクトリ
　　　　　┃　　　┗━　index.thml    　テンプレートファイル **
　　　　　┣━　__init__.py           Pythonのパッケージであることを示すファイル **
　　　　　┣━　admin.py              管理サイト用設定ファイル
　　　　　┣━　apps.py               アプリケーション構成設定ファイル
　　　　　┣━　forms.py              フォーム定義ファイル **
　　　　　┣━　models.py             モデル定義ファイル
　　　　　┣━　tests.py              テストコード記述ファイル
　　　　　┣━　urls.py               アプリケーション用ルーティング定義ファイル **
　　　　　┗━　views.py              ビュー定義ファイル
```

### 2-2. 開発サーバーの起動
Djangoプロジェクトをローカルマシン環境で動かすことができる、開発用サーバーを起動する

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py runserver
```

### 2-3. DBのマイグレーション
モデルに記述したDB(データベース)テーブル定義を基にマイグレーションファイルの自動作成を行ないます。
ここで言うマイグレーションとは、データベーステーブルの作成、変更、削除のことを指します。

#### 2-3-1. マイグレーションファイルの作成

データベースへの変更内容を記すマイグレーションファイルを作成します。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py makemigrations
```

#### 2-3-2. マイグレーションの実行

マイグレーションファイルの内容をデータベースへ反映します。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py migrate
```

#### 2-3-3. マイグレーション状況の確認

マイグレーション履歴はDjangoが管理する `django_migrations` に保存されています。
この履歴データを用いて、マイグレーションの適用状況を確認できます。
下記の showmigrations を実行すると、一覧とその適用状況が [X] で表示されます。
[X] であるマイグレーションファイルは適用済みを意味します。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py showmigrations ＜アプリケーション名＞

app
[X] 0001_initial
[X] 0002_remove_app_user
[ ] 0003_app_user
[ ] 0004_auto_20201210_0356
```

#### 2-3-4. マイグレーションのロールバック実行

マイグレーションの適用をある時点までデータベースを戻す際に使います。
下記は 0001_initial 適用直後まで戻す場合の記述です。

```:ターミナル
$ python manage.py migrate ＜アプリケーション名＞ 0001_initial
```

再度、showmigrtions で確認すると、以下のようになるはずです。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py showmigrations ＜アプリケーション名＞

app
[X] 0001_initial
[ ] 0002_remove_app_user
[ ] 0003_app_user
[ ] 0004_auto_20201210_0356
```

#### 2-3-5. スーパーユーザーの作成

スーパーユーザー（サイト管理者）を作成します。
コマンドを実行すると、対話式に、ユーザー名、メールアドレス、パスワードの入力を求められます。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py createsuperuser

ユーザー名: administrator
メールアドレス: administrator@example.ne.jp
Password:                 
Password(again):                 
Superuser created successfully.
```

#### 2-3-6. テストの実行

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```
上記はプロジェクト内の全テストを実行する際の記述です。
テスト範囲を限定して実行する際は、以下のように指定します。

- アプリケーション単位の実行　（app_a とapp_b アプリケーション内のテストを実行）

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test app_a app_b --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```

- テストモジュール単位の実行　（test_views.py 内のテストを実行）

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test ＜アプリケーション名＞.tests.test_views --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```

- テストクラス単位の実行　（TestAppListView クラスを実行）

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test ＜アプリケーション名＞.tests.test_views.TestAppListView --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```

- テストメソッド単位の実行　（test_list_app_successメソッドを実行）

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test ＜アプリケーション名＞.tests.test_views.TestAppCreateView.test_list_app_success --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```

- ディレクトリ内のテストを実行　（app ディレクトリ内のテストを実行）

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py test ＜アプリケーション名＞/ --settings ＜プロジェクト名＞.＜開発環境用のプロジェクト設定ファイル＞
```

#### 2-3-7. インタープリタの実行

Djangoプロジェクトの設定を読み込み、インタープリタを起動します。
Djangoのライブラリを使えるため、主にモデルを呼び出し、データベース操作をテストする際に用います。

```:ターミナル
(venv_＜プロジェクト名＞)$ python manage.py shell
```

---
#### (関連)
[【Python/Django】よく使うコマンドのまとめ(2) ＜パッケージのインストール＞](https://qiita.com/_whitecat_22/items/d1d06ea1e280c1665482)
[【Python/Django】よく使うコマンドのまとめ(3) ＜PostgreSQLの操作＞](https://qiita.com/_whitecat_22/items/264b13f9d7c2f020a7ad)
[【Python/Django】よく使うコマンドのまとめ(4)-前編- ＜本番運用：Amazon EC2 (Amazon Linux 2)＞](https://qiita.com/_whitecat_22/items/873befbe9de15421e840)
[【Python/Django】よく使うコマンドのまとめ(4)-後編- ＜本番運用：Amazon EC2 (Amazon Linux 2)＞](https://qiita.com/_whitecat_22/items/351d2ac5963c770284cb)

---
#### (編集後記)
テスト範囲を限定して実行するコマンドは、入力時によく躓きます。
ここにまとめることで、躓きを抑えたいと思います。