Django Settings for Production and Development: Best Practices
Join the DZone community and get the full member experience.
Join For FreeWhen you’re just starting out with Django, it can be overwhelming to see there’s no standard approach to deal with settings. However, there are a few simple best practices that work when you start needing more than the basic settings file.
What’s the problem? Django stores all the settings in a project-wide settings.py file. All is fine until the moment you need different settings for different environments(such as a production environment and a development environment to start with).
Of the necessity to have different settings files
Your development settings should be different from your production settings. Why?
- you should protect sensitive things like database passwords, api secrets, private keys in a separate file
- the behavior of production code is not suited for development : for example you don’t want to send an email when you’re developing new features
Here are a few things that may change from one environment to another:
- database details: database name, user name and password
- api keys
- your own private keys for encrypting data
- debug variables (DEBUG and TEMPLATE_DEBUG)
- path to different tools needed by your Django applications
- and any other flags needed to make your application work differently in development and in production
We’re going to compare three different ways to organize your settings when having one setting file doesn’t cut it anymore.
First solution: local settings
This solution relies on having one settings.py file with common settings and a local_settings file where you define environment-specific settings.
Let’s see:
### settings.py file ### settings that are not environment dependent try: from local_settings import * except ImportError: pass
### local_settings.py ### environment-specific settings ### example with a development environment DEBUG = True DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django', 'USER': 'django', 'PASSWORD': '1234', 'HOST': '', 'PORT': '', }
- Advantages: simple if you only need a development and a production environment (no staging) – the local_settings.py should stay out of source control and you need to have a separate one for development and production.
- Disadvantages: it limits what you can do with settings such as modify common settings in the local_settings for example. It can work for the most simple case though.
Second solution: environment-based settings
This is one from Ches Martin. It relies on having an environment variable pointing to the right python module. It has the advantage of being explicit, so you can name your specific settings files explicity (production file being production.py for example).
[myapp]$ls settings __init__.py defaults.py dev.py staging.py production.py
What happens when we do import settings? Settings is in this case a
package (a package in Python being a directory with an __init__.py file
inside), so when the interpreter loads the package it executes
__init__.py.
By default, let’s make it work in development environment.
### __init.py__ from dev import *
### default.py__ ### sensible choices for default settings
### dev.py from defaults import * DEBUG = True ### other development-specific stuff
### production.py from defaults import * DEBUG = False ### other production-specific stuff
How to use it in production and staging environments?
The trick is that the settings module location can be overriden by settings an environment Django variable. So we need to override that variable before starting our webserver. For example if you use Apache as your Django web server, modify your Apache configuration file with:
SetEnv DJANGO_SETTINGS_MODULE myapp.settings.production
Third solution: system-wide settings
### settings.py import os ENVIRONMENT_SETTING_FILE = '/etc/django.myproject.settings' ### this will load all environment file settings in here execfile(ENVIRONMENT_SETTING_FILE) ### all common settings ### ...
We can see one problem of doing it this way is that we cannot modify variables defined in the common settings.py file in the environment-specific files.
On the other hand, it simplifies the management of environment-specific settings files. Create a file for development, staging and production, secure it with some tight permissions, and forget about it.
To conclude
There are other ways to manage your settings, so you can experiment a little bit. Check the list of resources to know more about managing your settings. And drop a comment here if you want to share the way you’re doing it!
Resources:
- Splitting up the settings file, very comprehensive resource from the official Django website
- Django settings, again from the official Django website
- Extending Django settings for the real world from Yipit
- Django settings at Disqus: for a more complex and modular settings configutation.
- Stack Overflow:
- Django Snippets Keep settings.py in version control safely
Published at DZone with permission of Tommy Jarnac. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments