Django Environment Variables
Tags: django, python, webdev
Published: 2023-10-10 09:05:32

## Why do you need to use Environment Variables?

When you are building some Django project, you will need variables to manage, for example, database configuration, or to set the Debug option as True or False, especially when working with a project deployed in production that needs implementation. 

There are some packages that can help you out there, but personally, I use [django-environ](https://django-environ.readthedocs.io/en/latest/index.html).

## How to use django-environ and .env file
First of all, you need to install the package in your virtual environment:

```
pip install django-environ
```

Don't forget to freeze your packages list with:

```
pip freeze > requirements.txt

```

If you need to understand how pip freeze works, you can take a look on these good posts:
#### [Pip Freeze > Requirements.txt: A Beginner's Guide](https://dev.to/eskabore/pip-freeze-requirementstxt-a-beginners-guide-5e2m) by [Jean-Luc KABORE-TURQUIN](https://dev.to/eskabore) 
#### [Virtual environments: How to avoid Python dependency hell with venv and pip freeze](https://dev.to/exactful/how-to-avoid-python-dependency-hell-with-venv-and-pip-freeze-1k0h) by [Daniel Cooper](https://dev.to/exactful)

Now, you need to create a .env file where you will put all the variables you need. Let's see how you can build it.
First of all, you need to create the file, usually in the base directory of your project. Usually, the first variable I put in the .env file is the DEBUG option and SECRET_KEY.

```
# .env file
DEBUG=True
SECRET_KEY='your-secret-key'
```

So, now we have our first environment variable. Let's see how we can use it.
We need to open our settings.py file and change something. First of all, we need to import our package:

```
# settings.py file
[...]
import environ
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)


# Take environment variables from .env file
environ.Env.read_env(BASE_DIR / '.env')

# We are taking our secret key from .env file
SECRET_KEY = env('SECRET_KEY')

# Get from .env file if we are debugging or not
DEBUG = env('DEBUG')

[...]
```

This is the first step, but you can get more variables using this method. Other important variables I usually put in .env are variables for database. Let's take again our .env file and add our database variables:
```
# .env file
DEBUG=True
SECRET_KEY='your-secret-key'
DATABASE_TYPE=sqlite
SQLITE_DB_PATH=db.sqlite3
POSTGRES_DB_NAME=
POSTGRES_DB_USER=
POSTGRES_DB_PASSWORD=
POSTGRES_DB_HOST=
POSTGRES_DB_PORT=
```
As you can see, I put both SQLite and PostgreSQL variables. I manage these variables in my settings.py file:

```
# settings.py file
[...]

SQLITE_DB_PATH =  os.path.join(BASE_DIR, env('SQLITE_DB_PATH'))
if env('DATABASE_TYPE') == 'sqlite':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': SQLITE_DB_PATH,
        }
    }
elif env('DATABASE_TYPE') == 'postgresql':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': env('POSTGRES_DB_NAME'),
            'USER': env('POSTGRES_DB_USER'),
            'PASSWORD': env('POSTGRES_DB_PASSWORD'),
            'HOST': env('POSTGRES_DB_HOST'),
            'PORT': env('POSTGRES_DB_PORT'),
        }
    }
else:
    raise ValueError("Unknown database type specified in DATABASE_TYPE.")
[...]
```
In this case, I used the default SQLite database, but is enough to put 'postgresql' in the DATABASE_TYPE variable in the .env file to switch to Postgres (settings postgres variables, obviously).

These are some cases when you can use environment variables. You can also set the STATIC_ROOT path as variables, for example. 

## Tip
Make sure you add .env file in you gitignore file, in order to avoid to push your private variables in your repository. A better idea is to create a .env.example file, where you put your variables without values. In our case:
```
# .env.example file
DEBUG=
SECRET_KEY=
DATABASE_TYPE=
SQLITE_DB_PATH=
POSTGRES_DB_NAME=
POSTGRES_DB_USER=
POSTGRES_DB_PASSWORD=
POSTGRES_DB_HOST=
POSTGRES_DB_PORT=
```
So, in this way, you'll help to understand how your environment variables system works.

## Conclusions
This is how I manage environment variables. I hope this will help. If you have any suggestions, feel free to comment.