Using environment variables in Django: the Why and the How

Environment variables are basically variables that are loaded in the operating system on which your Django project is running. They are often used to provide values for settings.py variables such as DEBUG and SECRET_KEY.

Using environment variables in Django is considered “best practice” and is an essential part of the popular Twelve-Factor App Design methodology. They provide two main benefits for your project over just hard-coding variables in your settings file:

1. Ease of configuration

They provide an easy way to configure Django settings variables based on the environment. For example, imagine you set your DEBUG variable to an environment variable called $DJANGO_DEBUG. Now in your production server DJANGO_DEBUG can be set to False, while on your local machine it can be set to True. That way you don’t need to change the setting.py file to turn on debug mode when working locally.

You can do the same thing with your database credentials, API keys, and other essential setting variables that differ between local and production environments.

2. Security

Environment variables help mask important information like your secret key, database credentials, email credentials, etc. If you hard-code these variables and commit them to Git even once, they will be exposed to anyone who has access to the source code. This can be potentially dangerous. It is better to put these values in an environment variable instead.

How to use environment variables with Django

There are many ways for importing and using environment variables in Django. My favorite is django-environ. It provides a simple syntax for importing the variables, and it gives you an easy way of setting default values in case the variables are missing on the operating system. This will come handy and helps to avoid mistakes, as you will see in a moment.

You can install django-environ using pip:

$ pip install django-environ

Now create a .env file in your project directory and put your environment variables there:

DJANGO_DEBUG=True
DJANGO_SECRET_KEY=your-secret-key
DJANGO_DATABASE_URL=psql://user:somepassword@127.0.0.1:8458/database

Make sure you add the .env file to your .gitignore to make sure it does not get committed to Git.

If you are using docker for your project, you should add the env file to your docker-compose config.

Then you need to import these variables in Django. In the beginning of your settings.py file add this code to read in the variables from the operating system:

# settings.py
import os
from environ import Env

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

env = Env()
env.read_env(os.path.join(BASE_DIR, '.env'))

Now we can use the environment variables to populate the setting variables like this:

# settings.py
DEBUG = env.bool('DJANGO_DEBUG', default=False)
SECRET_KEY = env("DJANGO_SECRET_KEY")
DATABASES = {
    'default': env.db("DJANGO_DATABASE_URL", default="postgres://postgres@db/postgres")
}

Notice that django-environ provides type casting for the debug value. It means that it will convert it to a python Ture or False. We can also give it a default value in case the environment variable is missing on the operating system. So in case of DEBUG, it will default to False which is the safest option.

Another cool feature is the env.db that returns the database config dictionary and checks if the database is properly configured.

Now all you need to do is to create a .env file on your production server that looks essentially identical to the one you have locally, except that it sets the variables to the production-specific values.

There you go! You have successfully used environment variables in your Django project. This is an important step in any professional Django project. It provides an easy way of switching configurations between local development and production, and contributes to the security of your web application.

Subscribe via RSS