Modular settings for Django

This is the first post in a series about useful methods to simplify the development and the installation of Django. In this specific post I’m proposing a way to organize the settings into a module.

I have been always bothered by the settings file because it is needed to change it everytime we go from development server to production server: one has mainly to change the database, the debug option and the static/media options. This prevents us to copy at one time all the files (or we have to change the settings file elsewhere, e.g. in and it is unnecessarily complicated; also versioning is harder because we do not want to let sensitive information (secret key, etc.) be on internet. So after some thoughts (and maybe some readings on the web I do not remember) I came to a solution to this problem.

Here are the steps to follow:

  1. First let’s suppose that your project follows the following structure:

    Let be sure that the and files define correctly where are the Django settings:

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings")
  2. Now the idea is to turn our file into a Python module, in which the will store options common to dev and prod and which imports a dev/prod specific module. Since even for dev settings different persons can have different needs, we define only a generic file for the specific options, which will be derive in two other files: and So we delete and in place we create a the following directoy in the main module of our project:

    Note that the versioning tree will just contain these files, and the development tree will have further. The one specific to the prod server will only be created on it. This enables us to version only the common and dev settings.

  3. The head of the file contains the following lines:
    from os.path import join, abspath, dirname
    PROJECT_DIR = dirname(dirname(abspath(__file__)))
    DEBUG = True
    if DEBUG is True:
        from dev_settings import *
        from prod_settings import *
        join(PROJECT_DIR, 'templates'),
        join(PROJECT_DIR, 'static'),

    I have defined the project path in order to define system independent path for the static and template files (note that media should not be stored in the same way). The dots represents all the other common options, that you can find by comparing the dev files below and your canonical

  4. The is:
    from os.path import join
    ADMINS = (
        ('Admin', ''),
    # Directory where your files directories (media, static...) are stored
    # (absolute path).
    FILES_DIR = '/abs/path/to/files/'
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'project',
            'USER': '',
            'PASSWORD': '',
            'HOST': '',
            'PORT': '',
    # Absolute filesystem path to the directory that will hold user-uploaded files.
    # Example: "/home/media/"
    MEDIA_ROOT = join(FILES_DIR, 'media/')
    # URL that handles the media served from MEDIA_ROOT. Make sure to use a
    # trailing slash.
    # Examples: "", ""
    MEDIA_URL = '/media/'
    # Absolute path to the directory static files should be collected to.
    # Don't put anything in this directory yourself; store your static files
    # in apps' "static/" subdirectories and in STATICFILES_DIRS.
    # Example: "/home/media/"
    STATIC_ROOT = join(FILES_DIR, 'static/')
    # URL prefix for static files.
    # Example: ""
    STATIC_URL = '/static/'
    SECRET_KEY = ''
    del FILES_DIR

    This last file should be written to fit your project and indicates what are the options to fill.

  5. Copy the file in your development folder, rename it to and change the option. In the same way on the prod server create Now if you copy the tree from the dev to prod server, then will not be override; one just has to DEBUG to False.
  6. Finally be sure that your versioning system will ignore (and to be careful also

It would be useful to select automatically the adapted module (e.g. by looking if a wsgi instance is running), and this would allow to move the debug option in the specific settings to let us change this option if we want to debug the prod server (here one has to copy the prod settings as dev if one needs to debug the prod server).