Grouping Environment Variables in Django


Oftentimes values in settings.py are provided using environment variables. This is one of the easiest ways to do it. However it’s easy to misuse it, and variables get scattered across your code base. This makes it harder for DevOps to track which variables are needed in case they need to have a quick look at the code while configuring the deployment environment.

env.py

There is a simple solution. Make a file called env.py in the directory next to your settings.py. Insist that all the env variables should go there (except in special cases). You can make this as a project rule, and add it on a merge request check list. Let’s see an example:

# project/env.py
"""This module groups all environment variables together."""

import os


class Env:
    """
    DEBUG can take value of 0/1. ALLOWED_HOSTS is comma separated string (in
    case if you need multiple hosts).
    """

    # Basic config
    SECRET_KEY = os.getenv('SECRET_KEY', 'Xznsh5ACBqAnj3q6')
    DEBUG = bool(os.getenv('DEBUG', True))
    ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '*').split(',')

    # Database
    DATABASE_USER = os.getenv('DATABASE_USER', 'user')
    DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD', 'password')
    DATABASE_NAME = os.getenv('DATABASE_NAME', 'db')
    DATABASE_HOST = os.getenv('DATABASE_HOST', 'postgres.local')
    DATABASE_PORT = os.getenv('DATABASE_PORT', 5432)

Now, you can easily access your env vars from anywhere in the code. For example, when you are configuring the database connection, you can import the Env class, and just reference appropriate class attributes:

# project/settings.py
from .env import Env


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': Env.DATABASE_NAME,
        'USER': Env.DATABASE_USER,
        'PASSWORD': Env.DATABASE_PASSWORD,
        'HOST': Env.DATABASE_HOST,
        'PORT': Env.DATABASE_PORT,
    }
}

And that’s it! You should group all your env vars in one place, and it will always be easy to find them. And if you need to make changes, you will have only one place where you have to edit. In case you have many env vars, you can split env.py into directory i.e. Python package. But ideally you would want to have the least possible amount of configuration variables. For more complicated configuration you might consider using a config file, such as ini or YAML.

We're not spammers, and you can opt-out at any moment. We hate spam as much as you do.

powered by TinyLetter

See also