Search code examples
pythondjangoenvironment-variablesdecouplingpython-decouple

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


Solution

  • 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)