【Django3】環境構築と各種設定まとめ【Python3】

# はじめに

Django でシステム開発を行う際に必要な CLI のコマンドやディレクトリ構成、各種設定をまとめました。

Django は公式ドキュメントが充実しているので、時間がある方はそちらを見ましょう。
日本語多めですよ！
[Django公式ドキュメント](https://docs.djangoproject.com/ja/3.0/)

※順次追記していきます。

# システム構成

- Windows 10 Pro
- Windows PowerShell
- Python 3.8.1
- pip 20.0.2
- Django 3.0.3
- mysqlclient 1.4.6

## Django インストール

```powershell:PowerShell
# 仮想環境作成
python -m venv venv

# 仮想環境有効化
./venv/Script/activate

# Django インストール
pip install django
```

※PowerShell で仮想環境を有効化する際に発生するエラーについては、下記記事を参照。
[Qiita - 【Python3】開発環境構築《Windows編》 # PSSecurityException が発生した場合](https://qiita.com/hrgm_cmk/items/75a69953e6ed6de45926#pssecurityexception-%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88)

# Django CLI チートシート

## プロジェクト作成

```powershell:PowerShell
# カレントディレクトリに<Project Name>ディレクトリを作成し、その中にプロジェクトを作成
django-admin startproject <Project Name>

# カレントディレクトリ直下にプロジェクトを作成
django-admin startproject <Project Name> .
```

## アプリケーション作成

```powershell:PowerShell
python manage.py startapp <Application Name>
```

## 開発用サーバ起動

```powershell:PowerShell
# localhost:8000 に開発用サーバを起動する
python manage.py runserver [<Port>]
```

## 管理ユーザ作成

```powershell:PowerShell
python manage.py createsuperuser
```

コマンド実行後、「ユーザ名」「メールアドレス」「パスワード」の入力を求められる。
管理画面にログインするは、開発用サーバ起動後に`http://localhost:8000/admin/`にアクセスする。

## 静的ファイル集約

```powershell:PowerShell
python manage.py collectstatic
```

\<Project Name>/settings.py の STATIC_ROOT に定義されているディレクトリに、静的ファイルがコピーされる。
※ [静的ファイル](https://qiita.com/hrgm_cmk/items/b7c843778d84018cdbd5#%E9%9D%99%E7%9A%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%ABcss-javascript-images-) の項で後述

## マイグレーション

### マイグレーションファイル作成

```powershell:PowerShell
python manage.py makemigrations
```

データベースの変更内容が記述されたマイグレーションファイルを作成する。

### マイグレーション実行

```powershell:PowerShell
python manage.py migrate
```

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

# Django ディレクトリ構成

```
<Project Name> ┬ venv                   # 仮想環境用ディレクトリ
               ├ static                 # 静的ファイル格納ディレクトリ(※3)
               │ ├ css
               │ ├ js
               │ └ ...
               ├ templates              # テンプレート格納ディレクトリ(※1)
               │ ├ base.html            # テンプレートベースファイル
               │ └ <Application Name>
               │   └ ...                # テンプレートファイル
               ├ <Project Name>         # プロジェクト用ディレクトリ
               │ ├ __init__.py
               │ ├ asgi.py
               │ ├ settings.py          # プロジェクト用設定ファイル
               │ ├ urls.py              # プロジェクト用ルーティング定義ファイル
               │ └ wsgi.py
               ├ <Application Name>     # アプリケーション用ディレクトリ
               │ ├ static               # 静的ファイル格納ディレクトリ(※4)
               │ │ ├ css
               │ │ ├ js
               │ │ └ ...
               │ ├ migrations
               │ ├ templates            # テンプレート格納ディレクトリ(※2)
               │ │ └ ...                # テンプレートファイル
               │ ├ __init__.py
               │ ├ admin.py             # 管理サイト設定ファイル
               │ ├ apps.py              # アプリケーション構成設定ファイル
               │ ├ forms.py             # フォーム定義ファイル
               │ ├ models.py            # モデル定義ファイル
               │ ├ tests.py             # テストコード記述ファイル
               │ ├ urls.py              # アプリケーション用ルーティング定義ファイル
               │ └ views.py             # ビュー定義ファイル
               ├ manage.py              # ユーティリティコマンド実行用ファイル
               └ requirements.txt       # パッケージ一覧
```

## templates ディレクトリ

- プロジェクトディレクトリ直下に作成する場合 (※1)
- 各アプリケーションディレクトリ直下に作成する場合 (※2)

## static ディレクトリ

- プロジェクトディレクトリ直下の static ディレクトリ (※3)
    - 特定のアプリケーションに紐付かないプロジェクト全体に関する静的ファイルを格納
- 各アプリケーションディレクトリ直下の static ディレクトリ (※4)
    - アプリケーションに紐付く静的ファイルを格納

※ ただし、 webpack 等を使用している場合はプロジェクトディレクトリ直下 (※3) にまとめた方が都合が良いケースも多い。

# Django プロジェクト設定

## 言語とタイムゾーン

```python:settings.py
-- LANGUAGE_CODE = "en-us"
++ LANGUAGE_CODE = "ja"

-- TIME_ZONE = "UTC"
++ TIME_ZONE = "Asia/Tokyo"
```

## データベース

```python:settings.py
   # MySQL の場合
-- DATABASES = {
--     "default": {
--         "ENGINE": "django.db.backends.sqlite3",
--         "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
--     }
-- }
++ DATABASES = {
++     "default": {
++         "ENGINE": "django.db.backends.mysql",
++         "HOST": "127.0.0.1",
++         "PORT": "3306",
++         "NAME": "<DB Name>",
++         "USER": "<User Name>",
++         "PASSWORD": "<Password>",
++     }
++ }
```

## アプリケーションリスト

```python:settings.py
   # application アプリケーションを追加する場合
   INSTALLED_APPS = [
       "django.contrib.admin",
       "django.contrib.auth",
       "django.contrib.contenttypes",
       "django.contrib.sessions",
       "django.contrib.messages",
       "django.contrib.staticfiles",
++     "application.apps.ApplicationConfig",
   ]
```

新規アプリケーションを作成したら、プロジェクト用設定ファイルにアプリケーションを追加する。

## 静的ファイル（CSS, JavaScript, Images, ...）

### プロジェクト

```python:settings.py
   # 静的ファイル配信用URL
   STATIC_URL = "/static/"

   # 特定のアプリケーションに紐付けされない静的ファイル格納先ディレクトリ
++ STATICFILES_DIRS = (
++     os.path.join(BASE_DIR, "static"),
++ )

   # デプロイ時に collectstatic 管理コマンドによって静的ファイルが集約されるディレクトリ
++ STATIC_ROOT = "/var/www/example.com/static/"
```

プロジェクト用設定ファイルに静的ファイル格納ディレクトリを定義する。

### テンプレート

```html:index.html
++ {% load static %}
   <!DOCTYPE html>
   <html>
     <head>
       ...
++     <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
```

テンプレートファイル上部で static タグをロードすると、その後 static タグを使用して静的ファイルを相対パスで記述できる。

# Django ルーティング

「https://<example.jp>/application/」へのルーティングを追加する場合、プロジェクト用ルーティングファイルへの追記と、アプリケーション用ルーティングファイルの作成 or 追記を行う。

## プロジェクト

```python:settings.py
   TEMPLATES = [
       {
           "BACKEND": "django.template.backends.django.DjangoTemplates",
--         "DIRS": [],
++         "DIRS": [os.path.join(BASE_DIR, "templates")],
           "APP_DIRS": True,
           "OPTIONS": {
               "context_processors": [
                   "django.template.context_processors.debug",
                   "django.template.context_processors.request",
                   "django.contrib.auth.context_processors.auth",
                   "django.contrib.messages.context_processors.messages",
               ],
           },
       },
   ]
```

プロジェクトディレクトリ直下に templates ディレクトリを作成する場合は、上記の設定が必要。
各アプリケーションディレクトリ直下に templates ディレクトリを作成する場合は、"APP_DIRS" が True になっていれば大丈夫。

```python:urls.py
-- from django.urls import path
++ from django.urls import path, include

   urlpatterns = [
       path("admin/", admin.site.urls),
++     path("application/", include("application.urls")),
   ]
```

ルート（/）からのルーティングを記述する。
include 関数を使用することで、アプリケーション側へルーティング処理を移譲できる。

## アプリケーション

```python:urls.py
++ from django.urls import path
++ from . import views

++ app_name = "application"
++ urlpatterns = [
++     path("", views.IndexViews.as_view(), name="index")
++ ]
```

コマンドで作成されるアプリケーションディレクトリには urls.py が含まれないため、初めてアプリケーション側のルーティングを行う場合、自分で作成する必要がある。

```python:views.py
-- from django.shortcuts import render
++ from django.views import generic

++ class IndexView(generic.TemplateView):
       # アプリケーションディレクトリ直下に templates ディレクトリを作成する場合
++     template_name = "index.html"   
       # プロジェクトディレクトリ直下に templates ディレクトリを作成する場合
++     template_name = "<Application Name>/index.html"
```

template_name 変数に templates ディレクトリを起点としたテンプレートファイルの相対パスを格納することで、ビューとテンプレートを紐づける。