How we structure our Django web application's configuration settings
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.)
|
|