\ ポイント最大11倍! /

【Django】settings.pyの僕的ベストプラクティスをご紹介

  • 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で環境ごとに参照するモジュールを分岐

このようにすることで環境ごとに管理が簡単になり、メンテナンス性が向上します。

ぜひ、開発の参考にしてみてください。

この記事が気に入ったら
フォローしてね!

シェア・記事の保存はこちら!

この記事を書いた人

CFXLOGのアバター CFXLOG プログラマ

メイン言語はPython。本ブログでは、実務や普段の学習で学んだことをアウトプットしています。
基本情報技術者試験合格者。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)