Using the Settings Preset environment - SEL-Columbia/formhub GitHub Wiki


How is the Settings Preset environment different from the traditional practice in django?

In a traditional django environment, there is a single settings.py file in the application directory. Near the bottom of it will typically appear the line import local_settings. It is intended that this file contain any needed settings specific to a given installation. Unfortunately, every installation needs at least two such files: one for testing and/or development, and one for production use. A larger project may need many more: one for each developer, one for staging, one for testing a new version, etc. Continually editing or renaming this file can lead to vast confusion, and thus to possible errors in operation.

The idea of structured settings was suggested by Jacob Kaplan-Moss in his presentation the Best and Worst of Django. Briefly, structured settings are accomplished by turning the traditional pattern of imports on its head. The user selects from among many possible settings environments ("presets") by changing the value of the environment variable DJANGO_SETTINGS_MODULE. Each of these preset files, near the top of the file, contains an import of its parent. Ultimately, each limb will do from formhub.settings import *.

In this way, you can switch freely between production, staging, and multiple developers without editing Python code. The preset files are collected together in the formhub/preset directory.

12-factor configuration

Recently, the 12-factor movement has become quite popular. (see 12factor.net) This design suggests that no configuration information should ever be stored in source files, but should be defined in system environment variables. Two examples of 12-factor presets are provided. production_example.py uses separate environment variables for the user name and password for connection to the database. url_db.py uses a single URL formatted string to specify all of the values, including the database engine. It requires the dj_database_url module from https://github.com/kennethreitz/dj-database-url.


How to use Settings Presets in Formhub

Place all of your custom settings files into the formhub/preset/ directory. It is set up as a Python module with a blank __init__.py file.

Near the beginning of each preset file, from formhub.settings import * (or from some limb-level settings file)

Then set your DJANGO_SETTINGS_MODULE environment variable for your chosen custom setting.

A number of examples are included in the formhub/preset directory, including different database engines. Some are actually used during the testing and development of formhub.

VirtualEnv

Edit your virtual environment lib/postactivate file. You might want something like this...

  #!/bin/bash
  # This hook is run after this virtualenv is activated.
  export DJANGO_SETTINGS_MODULE=formhub.preset.staging_example

Command Line

You have the option of passing your settings preference on the command line. For example:

$ python manage.py test --settings=formhub.preset.mysql_test

Defaults

You might edit your personal settings file (such as ~/.bashrc) to include an appropriate environment variable:

export DJANGO_SETTINGS_MODULE=formhub.preset.example_sqlite

For the truly lazy, this version of manage.py will supply the default for you:

#!/usr/bin/env python
from __future__ import print_function
import os
import sys

if __name__ == "__main__":
    # altered for new settings layout
    if not any([arg.startswith('--settings=') for arg in sys.argv]):
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "formhub.preset.default_settings")
        print('Your environment is:"{}"'.format(os.environ['DJANGO_SETTINGS_MODULE']))
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

The default will be to use formhub/preset/default_settings.py