2

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

shuttle87
  • 15,466
  • 11
  • 77
  • 106
GetOffMyLawn
  • 1,362
  • 4
  • 14
  • 21

2 Answers2

3

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)
GetOffMyLawn
  • 1,362
  • 4
  • 14
  • 21
-1

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.

dacx
  • 824
  • 1
  • 9
  • 18
  • I originally implemented this method. What I don't like are it requires differentiating more files between dev and prod (manage.py and wsgi.py on top of the separate settings files) and it seems harder to keep track of with version control (obviously you would include dev.py and prod.py in gitignore, but then any variables they set are lost). I might consider going back to this, but I'd prefer a solution with python-decouple, environ, or a similar library. – GetOffMyLawn Jan 21 '21 at 21:06
  • You keep both in version control, they just load different things from the envs. – dacx Jan 21 '21 at 21:47
  • You mean separate settings files with separate env files too? – GetOffMyLawn Jan 22 '21 at 03:22
  • Exactly. The dev env file can perhaps even be checked into VC, depending on what you are exposing there. – dacx Jan 22 '21 at 10:28