How to avoid redundant manual assignment of environment variables in Django settings?
In my Django project, I store configuration variables in a .env file for security and flexibility. However, every time I introduce a new environment variable, I have to define it in two places: .env
and settings.py
.
As the project grows and the number of environment variables increases, settings.py
become filled with redundant redefinition of what's already in .env
.
Is there a way to automatically load all .env
variables into Django's settings without manually reassigning each one? Ideally, I want any new variable added to .env
to be instantly available from settings
module without extra code.
What I can think of is something like:
from dotenv import dotenv_values
env_variables = dotenv_values(".envs")
globals().update(env_variables)
Or even something a little bit better to handle values of type list.
for key, value in env_variables.items():
globals()[key] = value.split(",") if "," in value else value
# Ensure ALLOWED_HOSTS is always a list
ALLOWED_HOSTS = ALLOWED_HOSTS if isinstance(ALLOWED_HOSTS, list) else [ALLOWED_HOSTS]
But I do not like to mess around with globals()
.
so you to automatically load environment variables from .env
into django's settings but using globals().update()
is risky because it modifies the global namespace dynamically, which can make debugging harder
django-environ
simplifies loading environment variables while keeping settings.py clean.
pip install django-environ
modify your settings.py
import environ
#here we will initialize the environment variables.
env = environ.Env()
# it will read .env file
environ.Env.read_env()
#it will automatically load all the variables.
DEBUG = env.bool("DEBUG", default=False)
SECRET_KEY = env("SECRET_KEY")
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=[])
DATABASE_URL = env.db("DATABASE_URL", default="sqlite:///db.sqlite3")
now define you .env file and it will loaded immediately and would work seamlessly with django.