Webサービスの開発をDjandoで進めようとした場合、環境ごとの設定をどうやって分離したら良いかで悩みます。
そこで、環境ごとにファイルを分離して設定を管理する方法を紹介します。
設定方法
最終的なディレクトリ構成は、以下のようになります。
環境
- Python 3.8.2
- Django 3.0.3
base_dir
├ manage.py
├ .env
└ config
├ asgi.py
├ urls.py
├ wsgi.py
└ settings
├ __init__.py
├ base.py
├ local.py
└ production.py
手順1
元の設定ファイルsettings.pyのあるディレクトリに、settingsディレクトリを作成します。
$ mkdir config/settings
$ touch config/settings/__init__.py
手順2
元のsettings.pyを、settingsディレクトリにbase.pyにファイル名を変更して移動します。
$ mv config/settings.py configs/settings/base.py
手順3
base.py
設定ファイルから見たベースディレクトリの階層が、1階層深くなっているので入れ子を一つ増やします。
# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)
手順4
環境ごとに設定が変わるプロパティを、base.pyから削除します。
例えば、以下のようなものは環境ごとに設定が異なるかと思います。
- DEBUG:デバッグフラグ
- SECRET_KEY: 秘密鍵
- DATABASE:データベース接続
- MEDIA_ROOT:ストレージ設定
- STATIC_ROOT:静的ファイル配置
- LOGGING:ログ出力
手順5
環境ごとの設定を作成します。
開発用設定ファイルlocal.pyと本番用設定production.pyファイルを作成します。
$ touch config/settings/local.py
$ touch config/settings/production.py
requirements.txt
環境変数の設定django-environを使用すると便利なので、requirements.txtに入れおきます。(以下の解説でデータベースの接続例をPostgresにしているので、必要な場合はこちらも追記してください)
django-environ
psycopg2 # postgtresのDBを使用する場合
.env
環境ごとに設定する値を記述します。
DJANGO_SETTINGS_MODULE=config.settings.local
SECRET_KEY=hogehoge
DATABASE_URL=psql://<ユーザ名>:<パスワード>@<ホストIP>:<ポート>/postgres #postgresの場合
local.py
共通設定ファイルbase.pyの参照と、.envファイルの読み取りを記述します。
import environ
from .base import *
env = environ.Env()
env.read_env(os.path.join(BASE_DIR, '.env'))
## 各環境ごとの設定
# デバッグフラグ
DEBUG = TRUE
# 秘密鍵
SECRET_KEY = env('SECRET_KEY')
# データベース接続
DATABASES = {
'default': env.db()
}
手順6
manage.py wsgi.py
設定ファイルの読み込みをしていますので、その該当箇所を修正します。
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
実態としては、環境変数DJANGO_SETTINGS_MODULEに値を設定しているので、dockerを使用している場合は.envファイルで設定するなど各自の環境で調整をすれば良いです。