Consider avoiding the problem by putting your Django configuration in environment variables, with sensible defaults in settings.py
. Our team has switched to this technique after reading The Twelve-Factor App.
Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.
Here are a couple of examples from our settings.py
that start with a sensible default, then read an environment variable to check for overrides.
EMAIL_HOST = os.environ.get("MYAPP_EMAIL_HOST", "localhost")
# This is a list of lists in JSON, for example:
# export MYAPP_ADMINS='[["Your Name", "your_email@example.com"]]'
ADMINS = json.loads(os.environ.get("MYAPP_ADMINS", "[]"))
When choosing defaults, think about making it easy for a new developer to set up the project, as well as making the project secure by default.
You can see that the EMAIL_HOST
example is a simple string, while the ADMINS
example loads more structure from a JSON string. More complicated settings, such as LOGGING
are probably awkward to load from an environment variable. Either load small pieces of the setting from environment variables, such as the logging level, or use the environment variable to pass the path to a JSON, YAML, or INI file. Personally, I prefer YAML over JSON, because you can include comments.