How to manage local vs production settings in Django?
In settings.py
:
try:
from local_settings import *
except ImportError as e:
pass
You can override what needed in local_settings.py
; it should stay out of your version control then. But since you mention copying I'm guessing you use none ;)
Instead of settings.py
, use this layout:
.
└── settings/
├── __init__.py <= not versioned
├── common.py
├── dev.py
└── prod.py
common.py
is where most of your configuration lives.
prod.py
imports everything from common, and overrides whatever it needs to override:
from __future__ import absolute_import # optional, but I like it
from .common import *
# Production overrides
DEBUG = False
#...
Similarly, dev.py
imports everything from common.py
and overrides whatever it needs to override.
Finally, __init__.py
is where you decide which settings to load, and it's also where you store secrets (therefore this file should not be versioned):
from __future__ import absolute_import
from .prod import * # or .dev if you want dev
##### DJANGO SECRETS
SECRET_KEY = '(3gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'
##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."
What I like about this solution is:
- Everything is in your versioning system, except secrets
- Most configuration is in one place:
common.py
. - Prod-specific things go in
prod.py
, dev-specific things go indev.py
. It's simple. - You can override stuff from
common.py
inprod.py
ordev.py
, and you can override anything in__init__.py
. - It's straightforward python. No re-import hacks.
Two Scoops of Django: Best Practices for Django 1.5 suggests using version control for your settings files and storing the files in a separate directory:
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
The base.py
file contains common settings (such as MEDIA_ROOT or ADMIN), while local.py
and production.py
have site-specific settings:
In the base file settings/base.py
:
INSTALLED_APPS = (
# common apps...
)
In the local development settings file settings/local.py
:
from project.settings.base import *
DEBUG = True
INSTALLED_APPS += (
'debug_toolbar', # and other apps for local development
)
In the file production settings file settings/production.py
:
from project.settings.base import *
DEBUG = False
INSTALLED_APPS += (
# other apps for production site
)
Then when you run django, you add the --settings
option:
# Running django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local
# Running django shell on the production site
$ ./manage.py shell --settings=project.settings.production
The authors of the book have also put up a sample project layout template on Github.