GetOffMyLawn
GetOffMyLawn

Reputation: 1452

In settings.py, how should environment variables be loaded/set if they're only used in one environment?

I have a Django application where I'm handling environment variables using python-decouple and separate .env files. This works fine for variables that exist in both development and production environments, such as DEBUG.

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())

While DEBUG has distinct values in each environment, other variables like SECURE_HSTS_SECONDS only need to be set in production and do not need to be set at all in development. I'm currently just hard-coding these values in my settings.py file:

if not DEBUG:
    SECURE_HSTS_SECONDS = 60
    SECURE_HSTS_INCLUDE_SUBDOMAINS = True
    SECURE_REFERRER_POLICY = 'same-origin'
    SECURE_HSTS_PRELOAD = True
    SECURE_SSL_REDIRECT = True
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True

I suppose I could include these values in my dev .env file and just set them to their default values, but that seems unnecessary. Is there a cleaner way to implement this or a best practice? I'd prefer solutions that work with python-decouple

Upvotes: 2

Views: 4196

Answers (2)

GetOffMyLawn
GetOffMyLawn

Reputation: 1452

I didn't like the other answer because it seemed needlessly complex to add multiple settings files on top of already having separate .env files. I would have had to maintain separate env files, settings files, and wsgi.py/asgi.py files between my dev and prod environments.

Instead, I just included the same variables in my dev .env file as my prod .env file and manually set the default values. That way, I only need to maintain separate .env files between dev/prod. It would probably have been a little cleaner to just set the "default" parameter in the config() function within the settings file, but I liked the symmetry of each .env file having the same variables, so that was just a personal choice.

.env.dev :

DEBUG=True
ALLOWED_HOSTS=localhost, 127.0.0.1
SECURE_HSTS_SECONDS=0
SECURE_HSTS_INCLUDE_SUBDOMAINS=False
SECURE_HSTS_PRELOAD=False
SECURE_SSL_REDIRECT=False
SESSION_COOKIE_SECURE=False

.env.prod :

DEBUG=False
ALLOWED_HOSTS=mysite.com
SECURE_HSTS_SECONDS=2592000
SECURE_HSTS_INCLUDE_SUBDOMAINS=True
SECURE_HSTS_PRELOAD=True
SECURE_SSL_REDIRECT=True
SESSION_COOKIE_SECURE=True

settings.py :

DEBUG = config('DEBUG', cast=bool)

ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())

#HSTS settings
SECURE_HSTS_SECONDS = config('SECURE_HSTS_SECONDS', cast=int)
SECURE_HSTS_INCLUDE_SUBDOMAINS = config('SECURE_HSTS_INCLUDE_SUBDOMAINS', cast=bool)
SECURE_HSTS_PRELOAD = config('SECURE_HSTS_PRELOAD', cast=bool)
#HTTPS settings
SECURE_SSL_REDIRECT = config('SECURE_SSL_REDIRECT', cast=bool)
SESSION_COOKIE_SECURE = config('SESSION_COOKIE_SECURE', cast=bool)

Upvotes: 3

dacx
dacx

Reputation: 844

It is best to have two (dev/prod) or three (base/dev/prod) settings files. This is done by setting the DJANGO_SETTINGS_MODULE env variable accordingly.

Therefore, you can put settings for you production environment into a different file. Also, you can go for the three files approach where you add common settings into a base.py file which you in turn import into the prod.py and dev.py files.

Find examples in the django docs.

Upvotes: -1

Related Questions