We have a relatively long-standing Django web application , first written for Django 1.2. That was a long time ago and I didn't really know what I was doing, so when I began the web application I did what Django more or less suggests. I ran '
django-admin startproject
' to set up the initial directory structure and files, including the
settings.py
that contains various configuration settings for the application, and then started editing that generated
settings.py
to add all of the customizations we needed. This turned out to be a little bit of a mistake.
The problem is that what Django wants you to have in
settings.py
and how it's been structured has varied over Django versions; the
settings.py
from Django 1.2 is not what you'd get (and not really what you want) if you re-ran '
django-admin startproject
' today. Because I had mingled our local customizations into
settings.py
, I couldn't just have Django re-generate it and replace our old Django 1.2 version with the new, up to date one that would be set up like Django 1.9 wanted. So when I redid our
settings.py
for Django 1.9, I restructured how it was set up to put many of our settings into a separate file (or actually a cascade of them).
(I also made a little mistake by accidentally dropping a setting we needed because I hadn't commented it .)
My current approach is that the only things that go in
settings.py
itself are minimal modifications to Django settings that are already specified there, especially ones that are structured and ordered data, like
INSTALLED_APPS
,
MIDDLEWARE
, and
TEMPLATES
. Our modifications to all of these are commented with explicit markers, so I can find them when I need to propagate them into a new version of
settings.py
. All of our other settings go into a separate file, ((cslabsettings.py), which is pulled into
settings.py
in an addition at the end:
# CSLAB: # This is where our actual settings live. from app.cslabsettings import *
This has all of our settings for our application, and also some Django settings that aren't set in settings.py and so don't have to be modified there, such as
ADMINS
( cf ). Because we pull this into
settings.py
, all of the usual Django things just work without special configuration.
We then have a layer or two of additional settings files on top of this. For development, I have a
settings_dev.py
that imports (settings.py)) and then overrides bits and pieces (for example, to set '
DEBUG=true
'). To use it, I have a
manage_dev.py
which is just the standard
manage.py
modified to use
settings_dev
. I also have a
settings_wsgi.py
, which contains settings that are specific to running under WSGI instead of in management commands, and a
settings_wsgi_dev.py
that is for the obvious thing.
(Now that I look at
settings_wsgi.py
, it's possible that it has too many settings and should be trimmed back. The problem with having a whole cascade of settings files is that it's easy to lose track of what is set in what and what still needs to be overridden in the latest one.)
This is much the same idea as my ancient modular approach to Apache configuration , and for the same reason. The Django generated
settings.py
is pretty much a system supplied file, which means that periodically you want to replace it with a new system supplied version. The less you change in it, the less work you have to do when this happens.
(This entry is the long delayed explanation for the little bit at the end of this entry .)