[Django] django-environで環境変数を管理してみる

Djangoでプロジェクトを作っているとAPI-KEYなどの外部に漏れると問題のある情報を扱う場面が登場すると思います。

外部に漏れると困る情報は、環境変数にするのがよいのですが、都度ローカルの環境と本番の環境で環境変数を設定したりすると面倒なので、その辺の管理をdjango-environというパッケージにお任せしようという話です。

インストール

pipで簡単に入ります。

pip install django-environ

設定ファイルの作成

.envという名前のファイルをmanage.pyが置いてあるのと同じディレクトリに作成します。

今回はこんな感じです。

SECRET_KEY=^3wi#x1q(-luqb0l$o4be&au)b%0h10kmnytu*+5m0yb)(=+0k
DEBUG=True
ALLOWED_HOSTS=localhost,127.168.0.1
DATABASE_URL=sqlite:///db.sqlite3

中身は、それぞれと思いますのでご自分の環境に合わせて記述してください。

使い方

設定ファイルの読み込み

まずは、設定ファイルを読み込ませる。

import environ

env = environ.Env()
env.read_env('.env')

変数の読み出し

SECRET_KEY = env('SECRET_KEY')

普通に読みだすと文字列として読み出されます。

型を指定して読み出し

get_valueメソッドを利用するとキーワード引数castに型を指定する事で任意の型で値を読み出すことができます。

env.get_value('SECRET_KEY', str)

組み込みの型ついては簡略化されたメソッドも存在します。

  • str文字列として読み出す
  • int整数として読み出す
  • dict辞書
  • listリスト
  • tupleタプル
  • bool 真理値

リストやタプルについては値をカンマで区切っておくと複数の値を含んだ状態で読み出せます。
上の例だとALLOWED_HOSTSがそうです。

デフォルト値を設定する

.envに含まれない変数を読み出さそうとするとエラーを吐かれるので、それ防止にデフォルト値を読み出せるようにします。
デフォルト値を設定しておくには、二通りの方法があります。
一つは、インスタンス作成時に設定する方法
もう一つは先ほど紹介したget_valueメソッドを使う方法

まずは、インスタンス作成時に設定する方法から

import environ

env = environ.Env(DEBUG=(bool, False))

DEBUG = env('DEBUG')

インスタンス作成時にキーワード引数で変数を設定します。
デフォルト値はタプルで(キャストする型、デフォルト値)の順で渡します。

続いて、get_valueを用いる方法

import environ

env = environ.Env(DEBUG=(bool, False))

DEBUG = env.get_value('DEBUG', cast=bool, default=False)

キーワード引数defaultに設定するだけです。
簡略化されたメソッドでも同様にデフォルト値を扱えます。

DEBUG = env.bool('DEBUG', default=False)
データベース設定の簡略記法

dj-database-urlを使っている人には馴染みの記法で簡単にかけます。

EngineDjango BackendURL
PostgreSQLdjango.db.backends.postgresql_psycopg2postgres://USER:PASSWORD@HOST:PORT/NAME
PostGISdjango.contrib.gis.db.backends.postgispostgis://USER:PASSWORD@HOST:PORT/NAME
MSSQLsql_server.pyodbcmssql://USER:PASSWORD@HOST:PORT/NAME
MySQLdjango.db.backends.mysqlmysql://USER:PASSWORD@HOST:PORT/NAME
MySQL (GIS)django.contrib.gis.db.backends.mysqlmysqlgis://USER:PASSWORD@HOST:PORT/NAME
SQLitedjango.db.backends.sqlite3sqlite:///PATH
SpatiaLitedjango.contrib.gis.db.backends.spatialitespatialite:///PATH
Oracledjango.db.backends.oracleoracle://USER:PASSWORD@HOST:PORT/NAME
Oracle (GIS)django.contrib.gis.db.backends.oracleoraclegis://USER:PASSWORD@HOST:PORT/NAME
Redshiftdjango_redshift_backendredshift://USER:PASSWORD@HOST:PORT/NAME

これをDATABASE_URLとして設定しておけば、値の読み出しは

DATABASES = {
    'default':env.db(),
}

こんな感じにかけます。

ここまでの内容をまとめて設定ファイルを書くとこんな感じ

import os
import environ

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

env = environ.Env(DEBUG=(bool, False))
env.read_env(os.path.join(BASE_DIR, '.env'))

SECRET_KEY = env('SECRET_KEY')

DEBUG = env('DEBUG')

ALLOWED_HOSTS = env.list('ALLOWED_HOSTS')

...

DATABASES = {
    'default':env.db(),
}

長いので途中今回の話に関係のない部分は省略しています。

あとは、.envファイルを.gitignoreなどのファイルに追記しGit等の管理対象から外してしまえば環境ごとに設定ファイルを作っておく事で簡単に環境変数の管理ができます。