Django settings construction and configuration is fairly straightforward.
Configure Django and installed application settings, maybe add your own
project-specific settings, and let Django take care of the rest.
As long as you import settings from django.conf all the options and defaults
are properly resolved into the ultimate settings object.
However, every so often I run across a situation where I wish the Django
settings could do just a little bit more. Rather than try and wade into the
depths of Django runtime configuration and risk mucking things up, the
approach I take is to use a thin wrapper class around the already configured
settings and pass through all calls directly.
What we essentially want is “pass through” wrapper class like:
Fortunately, Django already has a slightly more complex version of this in the
django.conf.UserSettingsHolder class, so we’ll use that instead. I usually
have a common application in my Django projects and insert the settings
wrapper as the common.settings or common.conf module.
From there, we can add any number of “extra” settings variables or derived
methods. For instance, if we wanted to add a settings method to tell if our
database was SQLite or PostgreSQL using knowledge of the driver names, we
could implement some fairly simple methods:
While perhaps too simplistic and brittle for production use, the above example
illustrates how easy it is to add extra dynamic checks. To use the above
methods if very easy – just import settings from our module (here
common.settings instead of django.conf).
which outputs:
for a project configured with 'ENGINE': 'django.db.backends.sqlite3'.
In a typical Django project there are several file paths that are usually
derived and hacked into the settings file – the Django project root
directory, the Django admin media directory, and sometimes the path to the
settings file itself. Here are methods for our wrapped settings class to
intuit these paths:
And we can view our results with:
which outputs:
Putting a full file together with our simple extension methods. In our case,
the finished “common/settings.py” file will be:
While these contrived example method extensions are solving problems perhaps
best solved elsewhere (like in the actual project settings file), they serve
to illustrate a simple means of how to extend the Django settings module
easily and without interfering with the runtime settings configuration
process.