The django configuration file is pure python code, this gives us a lot of flexibility to setup settings when the application starts. Actually you could even modify settings in runtime, but promise me you won’t do this, ever!

Imagine you have an open-source django project, you have your code in github or something like that, but you probably don’t want to publish your DATABASES configuration. Or maybe you can add all your server configuration under version control, it’s private, great, but your local configuration is probably different too, you will need to set DEBUG = True at least.

There are a few ways to extend the file…

Use the –settings option

The command has a --settings option that you can use to specify a different settings file, so you could have a file similar to:

from settings import

DEBUG = True
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',

And locally you use:

$ python runserver --settings=local_settings

This is the simplest way to extend the file and is probably enough for most situations, but let’s take a look in other options.

Importing from

This method is the opposite from above. In the end of your you add:

    from local_settings import
expect ImportError:

Now you file won’t need to import anything from, just set your configuration variables. And you don’t need to pass --settings anymore.

Adding code dynamically to

This is similar to the method above but gives you more flexibility. Imagine you need a file similiar to this:

DEBUG = True
MIDDLWARE_CLASSES = MIDDLWARE_CLASSES + ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INSTALLED_APPS = INSTALLED_APPS + ('debug_toolbar',)

How could you use MIDDLWARE_CLASSES or INSTALLED_APPS from if you didn’t import those? Here is the answer:

import os

PROJECT_ROOT = os.path.dirname(file)
    execfile(os.path.join(PROJECT_ROOT, ''), globals(), locals())
except IOError:

The trick here is the execfile function, it reads the content of the file and appends it to the file you calling from. In the end, it’s like the contents of you file are inside

Host specific settings

Now you already have a way to customize your settings locally, just create a file, don’t add it under version control, and add one of these code snippets in the end of your

But what if you need specific settings per host? You have this project that runs on multiple servers, and you want specific settings for each one. You could create a settings_<SERVER_HOSTNAME>.py file, and import dynamically:

import socket
import os

PROJECT_ROOT = os.path.dirname(file)
settings = '' % socket.gethostname()

    execfile( os.path.join(PROJECT_ROOT, settings), globals(), locals())
except IOError:

To view your hostname just execute:

$ hostname

so, in my case I have a file called


That’s it! How I said in the beginning, is just python, this gives us a lot of power to customize our settings dynamically. If you have another idea let us know.

See you!