Irrational Exuberance!

A Different Approach to

November 28, 2008. Filed under django

A couple weeks ago when I spoke at Django NYC, in one of my slides I introduced the trick for Django, and on the next slide I mentioned a slight variant on the standard trick, which I've tried to introduce before, but the idea got lost in the midst of the longer article.

The Real

The original version of this trick is simple and extremely useful. At the bottom of your file, add these four lines

    from local_settings import *
except ImportError:

Then you can create a custom file with overrides for the settings for your machine, and you're golden.

When you're creating public repositories, you make sure not to place your into the version control, but you can still create a file that others cp and then edit to their liking.

The Variant I Speak Of

The first time I used this variant I was working on an app which I deployed two places: on my VPS and on my personal machine. I wanted to be able to keep the settings for both in version control, but without any needing to make modifications each time I updated the checked out project.

My solution went like this:

  1. Have the file which contains all shared settings, and still ends with:

        from local_settings import *
    except ImportError:
  2. Store the settings for my development machine in and store the settings for VPS in

  3. On each development, create a file that only contained one line. For my development server the line is:

    from devel_settings import *

    and for my VPS the line is:

    from vps_settings import *

Doing that, I can easily modify both setups and keep them in version control incase I want to deploy the project on another machine.

Essentially what's being done here is something akin to subclass settings files and overriding just what is necessary. You can get carried away with this stuff if you want to, and have a settings buffet where you combine pieces as you like.

For example, you could have a file named that looks like this:

CACHE_BACKEND = "memcached://"

and you could have a file named

ROOT_PATH = os.path.dirname(__file__)
DATABASE_NAME = os.path.join(ROOT_PATH, 'db.sqlite')

Finally, in your you'd import the pieces you wanted (as well as override what you want to modify):

from site_caching_settings import *
from sqlite_settings import *
CACHE_BACKEND = "localmem:///"

You're Right. It doesn't scale.

I think the obvious weakness to this approach is that it doesn't scale well, and it isn't a replacement for the standard trick, but it has served me quite well for projects that only need to be deployed in a small number of environments. For example, work and personal projects that are not intended to be reusable or pluggable apps.