Steven Mercatante

Steven Mercatante

Using environment specific settings in a Django project

When you start a new Django project using the django-admin startproject helper, it automatically generates a settings.py module for you. This is great when you want to start developing quickly, but you'll want to change this as soon as you're ready to deploy to a production server. Ideally you'll have different settings for each environment (local, production, testing, etc.) You can do this by creating multiple settings modules within a settings package.

First, create a settings package in your project's main package (if you used django-admin startproject blog you should have a blog package - add your settings package within the blog package.) Create four new modules, base.py, local.py, prod.py and testing.py inside your new settings package. Your directory structure should look similar to this:

blog/
|- blog/
|- settings/
|- __init__.py
|- base.py
|- local.py
|- prod.py
|- testing.py
|- __init__.py
|- settings.py
|- urls.py
|- wsgi.py
|- manage.py

Copy and paste the contents of settings.py into settings/base.py - this will act as the core of our settings. Once you've done that, delete settings.py - we don't need it anymore.

Now's a good time to change a few default settings.

Change DEBUG = True to DEBUG = False. By setting this to False, we make sure that debug information won't be displayed on the production site.

Change SECRET_KEY = <some long string> to SECRET_KEY = os.environ['SECRET_KEY'] (feel free to change the string SECRET_KEY to something more specific, like BLOG_SECRET_KEY.) This is a really important step because you never want to commit sensitive information like a secret key to your repo. At this point I like to define my secret key environment variable. Depending on the shell you use, edit its .rc file (I use zsh so I'll edit my ~/.zshrc file and add something like this: export BLOG_SECRET_KEY="ZLmrdiNrFVom)GF4fAvX".)

We now need to import the base settings into each of the environment modules. Add from .base import * to the top of your local.py, prod.py and testing.py modules. In local.py override DEBUG and set it to True.

At this point we have environment specific settings, and have removed sensitive information from our codebase. The last step is to actually use these new settings modules. If you're expecting to just run ./manage.py runserver and everything will work, well... it won't. We need to tell Django which settings module to use. So we need to run ./manage.py runserver --settings=blog.settings.local. If you want to run the test suite you'd call ./manage.py test --settings=blog.settings.testing.

Keep in mind that you're not limited to just local, prod and testing environments - you can add any number of environments and have specific settings for them using this approach!