Django python-environ を使って設定を分離する方法

python-environを使うと環境毎にsettings.pyを分けなくても環境変数や、.envファイル、デフォルト値で設定を定義できる様になります。様々なcastに対応しているため設定値を安全に変換することもできます。

今回はpython-environの使い方を解説します。

インストールと .envファイル作成

以下のコマンドでインストールできます。

pip install django-environ

.envファイルをsettings.pyと同じディレクトリに作成します。

バージョン管理している場合.envを.gitignoreに追加します。(tip:変数の設定例として.env.exampleを作成しても良いでしょう)

DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:un-githubbedpassword@127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db
CACHE_URL=memcache://127.0.0.1:11211,127.0.0.1:11212,127.0.0.1:11213
REDIS_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient&password=ungithubbed-secret

注)settings.pyではDEBUG=Trueと書くのでDEBUG=onと書いてあるのに違和感があるかもしれませんが、DEBUG=Trueと書いて問題ありません。

リポジトリにあるenviron.pyには

BOOLEAN_TRUE_STRINGS = ('true', 'on', 'ok', 'y', 'yes', '1')

と書いてあり、また、以下の様にbool値を判定しています。

try:
    value = int(value) != 0
except ValueError:
    value = value.lower() in cls.BOOLEAN_TRUE_STRINGS

よって.envにDEBUG=Trueと書いてもTrueを小文字変換した結果がBOOLEAN_TRUE_STRINGSに含まれているため、settings.pyではDEBUGにbool型のTrueが代入されます。

.envファイルのデータを読み込む様に編集したsettings.pyは以下の様になります。

import environ
env = environ.Env(
    # 型とデフォルト値を定義
    DEBUG=(bool, False)
)
# .envを読み込む
environ.Env.read_env()

# DEBUGがos.environで読み込めない場合はFalse
DEBUG = env('DEBUG')

# SECRET_KEYがos.environで読み込めない場合はImproperlyConfigured例外が発生
SECRET_KEY = env('SECRET_KEY')

# DB接続urlをpsql://user:pass@127.0.0.1:8458/dbの様にパースします
DATABASES = {
    # os.environ['DATABASE_URL']を読み込みます。なければImproperlyConfigured例外が発生します
    'default': env.db(),
    # os.environ['SQLITE_URL']を読み込みます
    'extra': env.db('SQLITE_URL', default='sqlite:////tmp/my-tmp-sqlite.db')
}

CACHES = {
    # os.environ['CACHE_URL']を読み込みます。なければImproperlyConfigured例外が発生します
    'default': env.cache(),
    # read os.environ['REDIS_URL']を読み込みます
    'redis': env.cache('REDIS_URL')
}

以下略

以下の順で読み込みます。未定義の場合は例外が発生します。

  1. 環境変数
  2. .envファイル
  3. デフォルト値

サポートしている型

サポートしている型は以下の通りです。

  • str
  • bool
  • int
  • float
  • json
  • list
  • tuple
  • dict
  • url
  • path (environ.Path)
  • db_url
    • PostgreSQL: postgres://, pgsql://, psql://, postgresql://
    • PostGIS: postgis://
    • MySQL: mysql://, mysql2://
    • MySQL for GeoDjango: mysqlgis://
    • SQLITE: sqlite://
    • GeoDjango用のSPATIALITE: spatialite://
    • Oracle: oracle://
    • MSSQL: mssql://
    • PyODBC: pyodbc://
    • Redshift: redshift://
    • LDAP: ldap://
  • cache_url
    • Database: dbcache://
    • Dummy: dummycache://
    • File: filecache://
    • Memory: locmemcache://
    • Memcached: memcache://
    • Python memory: pymemcache://
    • Redis: rediscache://
  • search_url
    • ElasticSearch: elasticsearch://
    • Solr: solr://
    • Whoosh: whoosh://
    • Xapian: xapian://
    • Simple cache: simple://
  • email_url
    • SMTP: smtp://
    • SMTP+SSL: smtp+ssl://
    • SMTP+TLS: smtp+tls://
    • Console mail: consolemail://
    • File mail: filemail://
    • LocMem mail: memorymail://
    • Dummy mail: dummymail://

以下はlist, tuple, dictを.envに書く例です。dict型の区切り文字は,(コンマ)でも;(セミコロン)可能です。他のデータ型の書き方を知りたい場合はリポジトリにあるtest_env.txtやtest.pyが参考になります。

LIST_FOO=a,b,c
TUPLE_FOO=(a,b,c)
DICT_BAR1=key=val,foo=1.1
DICT_BAR2=key=val;foo=1.1;baz=True

使うコツ

私なりの使い方を紹介します。settings.pyは以下の様に書きます。

import environ

# 引数なしでオブジェクト作成
env = environ.Env()

# .envを読み込む
env.read_env()

# デフォルト値なし
DEBUG = env('DEBUG')

# 型指定, デフォルト値あり
BOOL1 = env('BOOL1', cast=bool, default=True)

# ショートカットを使って型を指定
BOOL2 = env.bool('BOOL2', default=True)

設定項目毎にcastやdefaultを定義した方がわかりやすいです。

ショートカットを使うと短く書けます。どの様なショートカットがあるかはコードを見て確認した方が良いです。

メール設定

djangoのメール設定は次のように書けます。

EMAIL_CONFIG = env.email_url(
    'EMAIL_URL', default='smtp://user@:password@localhost:25')

vars().update(EMAIL_CONFIG)

SQLite urls

SQLiteはファイルベースのデータベースに接続します。ファイルベースのデータベースのurlは、絶対パスの場合スラッシュを4つ書く必要があります。

sqlite:////full/path/to/your/database/file.sqlite

複数のenvファイル

複数のenvファイルを扱えます。環境変数を使って指定できます。

次の例はother-envという名前のファイルを指定しています。

ENV_PATH=other-env ./manage.py runserver
スポンサーリンク
スポンサーリンク