We've all faced a situation where we need to change some configuration inside our settings.py
but only for a specific environment. If this happens on our own machine, we might be tempted to simply change it, knowing we cannot never commit it because it might cause problems. If you need to change a configuration for a remote server, then this won't work, and you need a proper solution.
There are a couple of ways to solve this:
settings.py
for different environments, but don't do this!settings.production.py
and settings.development.py
and then load them from settings.py
. This is already better..env
file. Create one per environment and load it from settings.py
. This will also work but you'll need to manage your different .env
files.I will go with the last one because it is the one more in line with the The twelve-factor app that says:
The twelve-factor app stores config in environment variables (often shortened to env vars or env). 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.
So, the most basic way to load a variable from the environment is using os.environ
. Here's a basic example to load SECRET_KEY
from an env var:
import os
SECRET_KEY = os.environ['SECRET_KEY']
This will throw an error if the env var is not defined which is fine in this case because you do not want your app to run without a defined SECRET_KEY
. How about DEBUG
? Defined or not, we could/should still run the app. We can consider it to be always false (as the default) and only make it to true once it's defined as an env var. This is how to do it:
import os
DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true'
This will not crash due to the .get()
, but you need to keep in mind that an env var is passed as a string. If you need anything other than a string, you'll need to convert is yourself. In this case, we get the DEBUG
env var but get "False" if it's not defined. Once we have this and just to be safe, we lower case it because it might be written as "True", "TRuE", ... Finally, we can check if it's equal to "true" and in that case DEBUG
is really defined as True
.
This is a simple but effective technique that you can apply to any configuration inside settings.py
to specify it per environment.
If you liked this post and want to read more, take a loot at these: