Production/Development settings switching with django-apache

When we work in a web project it’s usual to have a devlopment version and a production version that only differ in some configuration parameters (database, user authentication, file paths…). Usually, the development version is deployed from the version control repository, and you have to tune some settings before restarting the service. With RoR you got that for free but it’s a feature I find lacking in django. Until today.

I use apache for serving the django apps through mod_pyhton, but I test the development version with the server included in the framework. We will use a system environment variable to select the appropiate settings file. We will call this variable DJANGO_SETTINGS_ENVIRONMENT, and we will set it up in the apache-python configuration block using the SetEnv directive. This is an example configuration:

    <Location "/djangoproject">
        SetHandler python-program
        PythonHandler django.core.handlers.modpython
        SetEnv DJANGO_SETTINGS_MODULE djangoproject.settings
        SetEnv DJANGO_SETTINGS_ENVIRONMENT production
        PythonOption django.root /djangoproject
        PythonInterpreter djangoproject
        PythonPath "['/var/www/django/', '/var/www'] + sys.path"
    </Location>

Now, we have to detect the parameters we suspect that will change between configurations, and move all these params from the main settings.py file to two separated files. I created a “settings” folder in the project root, and there I laid the two configuration files:

    djangoproject\
        settings.py
        settings\
            development.py
            production.py

Next we modify settings.py to include the sub-configuration file for the selected environment. In order to do this, I used the execfile() function (I don’t know if there’s a better suited function to include code in python :P), and added the following files to my settings.py file. You have to note that if you have global parameters that must be known by the parameters defined inside the sub-configuration files, you have to declare them prior to these lines!

    import os
    # this line should be included always to make our project "path-relative"
    ROOT_PATH = os.path.abspath(os.path.dirname(__file__))

    DEBUG = True
    TEMPLATE_DEBUG = DEBUG

    # include sub-configuration settings. Default environment is 'development'
    DJANGO_SETTINGS_ENVIRONMENT = 
        os.environ.get('DJANGO_SETTINGS_ENVIRONMENT') or 'development'
    execfile('%s/settings/%s.py' % (ROOT_PATH, DJANGO_SETTINGS_ENVIRONMENT))

Done. Now we can deploy for production the same project we were working with under development, but using different settings for each environment.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s