How do you deal with settings changes that manipulate Python for different environments? That’s a question that came up as I was doing my Django Twitch stream (shameless plug ) tonight.
In my current project configuration, I have multiple settings files for different environments like settings/development.py, settings/production.py, and so on which inherit settings from a settings/base.py file. I’m trying to switch to a scheme that only uses a single settings file and reads stuff externally. I happened to select goodconf, but you can totally do something similar with django-environ.
My trouble with this switch is that I don’t know what to do when one of my other settings files manipulated Python. For instance, here is settings/development.py:
The only substantial change that this settings file is doing is configuring django-debug-toolbar. To do that, I’m monkeying with INSTALLED_APPS and MIDDLEWARE at the Python level (i.e., manipulating lists).
If you use a tool like django-environ, how do you like to deal with these environment-specific customizations? It looks like django-configurations might support this with setup methods. I’m interested to see other techniques that people use.
I only use two settings files in my projects.: settings.py and test_settings.py. My main settings.py file uses django-environ and has good, local defaults which are overrideable with environment variables.
While I don’t use debug_toolbar, I would do something like:
My test_settings.py is disabled migrations, using a faster password hasher, disables logging, and basically a bunch of other tricks to make my testsuite run as fast as possible.
Your production settings shouldn’t be in git so set them via environment variables and/or SECRETS with your hosting provider.
It’s a personal preference. I have worked on projects with dozens of settings per project and 1000+ line settings files that try to account for particular environments, and two feels like the right mix for me.
Splitting out your testing config makes CI/testing a bit easier because you can point pytest at the test_settings.py and avoid having to configure extra environment variables. I try to avoid having to set any outside of DATABASE_URL.
I thought that would be a good reason to program as much configuration unfolding as possible. Nonetheless, anything works as long as you practice CI/CD, by whatever means necessary
I think it’s more readable too
That’s debatable of course but my example code has a very low complexity and few caracters so for many people I think it’s still readable.
Honestly, I don’t really read configuration files much anymore, I use the djcli setting command to print out setting values after interpretation. Basically it’s the same as echo 'from django.conf import settings; print(settings.SOME_SETTING)' | manage.py shell which I used prior to having djcli.
Anyway, splitting it in modules is fine - it worked for me prior to adhering to the 12factor practice, but 1000 lines would look ok for me given the low complexity of a programed configuration file. I recon there’s definitely a learning curve for developers who aren’t familiar with environment variables, so, that would be the only inconvenient to report in my exerience.