- settings.pyのベストプラクティスが知りたい!
本記事では、僕が個人開発で使っているsettings.py
の内容を公開します。
ぜひ参考にしてみてください。
【Django】settings.pyの僕的ベストプラクティスをご紹介
ここでは、以下の内容をお伝えします。
- ディレクトリ構成
- 各ファイルの内容
- __init__.py
- base.py
- development.py
- production.py
順番に解説します。
ディレクトリ構成
プロジェクトフォルダの配下にsettings
フォルダを作り、その下に開発環境/本番環境ごとに設定ファイルを配置します。
project_root/
├── core/
│ ├── __init__.py
│ ├── settings
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── development.py
│ │ └── production.py
│ └── ...
├── myapp/
│ ├── __init__.py
│ └── ...
└── manage.py
settings
フォルダ配下に設定ファイルは、それぞれ以下のような使い分けです。
モジュール名 | 役割 |
---|---|
__init__.py | 環境変数により開発・本番を切り替え |
base.py | 本番・開発共通の設定 |
production.py | 本番環境用の設定 |
development.py | 開発環境用の設定 |
こうすることで、環境変数を切り替えるだけで設定内容が勝手に切り替わります。
__init__.py
__init__.py
には、開発/本番環境ごとに設定ファイルを切り替えています。
環境変数DJANGO_ENV
を使った条件分岐です。
import os
from .base import *
environment = os.getenv("DJANGO_ENV", "development")
if environment == "production":
from .production import *
else:
from .development import *
仮にDJANGO_ENV
が未設定の場合には開発環境用のdevelopment.py
が採用されます。
一方でDJANGO_ENV=production
にした場合には、本番環境用のproduction.pyが採用される仕組みです。
base.py
本番環境、開発環境を問わず共通の設定をbase.py
に書きます。
from pathlib import Path
# DIRECTORY
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# DEFAULT
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
LANGUAGE_CODE = "ja"
TIME_ZONE = "Asia/Tokyo"
USE_I18N = True
USE_TZ = True
# URL
ROOT_URLCONF = "core.urls"
WSGI_APPLICATION = "core.wsgi.application"
# STATIC
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"
# APPS
DEFAULT_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MY_APPS = [
]
THIRD_PARTY_APPS = [
]
INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + MY_APPS
# MIDDLEWARE
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
# PASSWORD VALIDATION
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# TEMPLATES
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
settings
フォルダの下に配置してるため、BASE_DIR
ではparent
を3つ書いています。
また、INSTALLED_APPS
は特性に応じてリストを分けています。
その他には、特段変わった設定は書いていないと思います。
development.py
ここでは開発環境特有の設定を書き込んでいきます。
import os
from dotenv import load_dotenv
from .base import *
# 環境変数読み込み
load_dotenv(BASE_DIR.parent / ".env")
# BASIC SETTINGS
SECRET_KEY = "development_secret_key"
DEBUG = os.environ.get("DEV_DEBUG", "False") == "True"
ALLOWED_HOSTS = ["*"]
# DATABASES
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
ここでは仮として、プロジェクトの一つ上の階層に.env
を配置しているケースにしました。
production.py
こちらでは本番環境特有の設定を書き込みます。
import os
from dotenv import load_dotenv
from .base import *
# 環境変数読み込み
load_dotenv(BASE_DIR.parent / ".env")
# SECURITY
SECRET_KEY = os.getenv("PROD_SECRET_KEY")
DEBUG = os.getenv("PROD_DEBUG", "False").lower() == "true"
ALLOWED_HOSTS = os.getenv("PROD_ALLOWED_HOSTS", "localhost,127.0.0.1").split(",")
# DATABASE
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.getenv("PROD_DB_NAME"),
"USER": os.getenv("PROD_DB_USER"),
"PASSWORD": os.getenv("PROD_DB_PASSWORD"),
"HOST": os.getenv("PROD_DB_HOST"),
"PORT": os.getenv("PROD_DB_PORT"),
}
}
基本的には環境変数から値を読み取る想定です。
.env
環境変数は、以下のようなものを記載します。
# DEVELOPMENT SETTINGS
DEV_DEBUG=True
# PRODUCTION SETTINGS
PROD_SECRET_KEY=
PROD_DEBUG=False
PROD_ALLOWED_HOSTS=
PROD_DB_NAME=
PROD_DB_USER=
PROD_DB_PASSWORD=
PROD_DB_HOST=
PROD_DB_PORT=
プロジェクトに応じて、適宜加筆修正は行っています。
まとめ
僕のベストプラクティスは以下の通りです。
- settingsディレクトリを用意
- 役割ごとにモジュールを分ける
- __init__.pyで環境ごとに参照するモジュールを分岐
このようにすることで環境ごとに管理が簡単になり、メンテナンス性が向上します。
ぜひ、開発の参考にしてみてください。
コメント