I’ve been developing Django applications for quite some time now, and I’ve amassed a few tricks. Here’s an example of a settings file I’ve created for a recent project. I’ll explain all of the bells and whistles below.
Here’s the whole file: http://gist.github.com/214361
The rest is after da jump!
Debug Switch
Using this bit of pre in place of plane old DEBUG=True will allow you to have your Django project automatically switch out of debug mode when on the production server. Sometimes I’ll add several sites to the if statement so that on testing servers, QA testers don’t get confused.
# Set DEBUG = True if on the production server
if socket.gethostname() == 'your.domain.com':
DEBUG = False
else:
DEBUG = True
Database Settings
I always leave the database bit blank so you are forced to include a “local_settings.py” (talked more about below). I like to run a sqlite database on my localhost, and a postgresql or mysql database on my production server. This way, you don’t have to worry about ignoring your “settings.py” file in your repository updates. Just have your repository ignore “local_settings.py”.
# The database settings are left blank so to force the use of local_settings.py below DATABASE_ENGINE = '' DATABASE_NAME = '' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_HOST = '' DATABASE_PORT = ''
Media Root
This line will automatically build a variable which stores the path to this file (your settings). I always store my media in a directory called media within the project. Using this, your media directory is built dynamically so you don’t have to fiddle with your settings each time you go production. This also goes for any other directories you want to include.
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__)) MEDIA_ROOT = os.path.join(PROJECT_PATH, 'media')
Context Processors
These guys can get annoying sometimes. If you don’t write your context processors into your settings, they’re going to default and leave out things like the request (depending on which version of Django you have I believe).
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.media',
'django.core.context_processors.request',
)
Using Debug Switches
I’ll probably get yelled at for putting this in, but to keep things neat, I like to only include what’s necessary in my context processors. Here you’ll see that the debug processor is only turned on if the server is not production. Same for the i18n processor, but with the i18n switch. More about the “debug toolbar” later.
if DEBUG:
TEMPLATE_CONTEXT_PROCESSORS += ('django.core.context_processors.debug',)
if USE_I18N:
TEMPLATE_CONTEXT_PROCESSORS += ('django.core.context_processors.i18n',)
if DEBUG:
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
Template Directories
I like to put my template directories within their respective application directories. So using this looping method of peeking in each app directory for a templates directory will automatically add any dir called “templates” within your project dir to the templates tuple.
# Dir Structure
# + Application
# + templates
# + Application
# - someTemplate.html
# - models.py
# - views.py
# - otherAppSpecificFiles.py
# + OtherApplication
# + Templates
# - base.html
# - settings.py
# - urls.py
# - otherfiles.py
TEMPLATE_DIRS = ()
for root, dirs, files in os.walk(PROJECT_PATH)
if 'templates' in dirs: TEMPLATE_DIRS += (os.path.join(root, 'templates'),)
Must Have Django Applications
Below are some must have Django applications. I’ll list those in a sec, but one very important issue is displayed here as well. The time has come to STOP using mod_python to deliver your applications!!! Everyone should be aboard with wsgi these days, and wsgi has a neat ability. WSGI is able to dynamically load the applications appending the current directory to your Python path. What’s sweet about this is that you don’t have to have “myproject.application” anymore. You can just write “application”. This gives your project more portability! Portability = Rad so this is a good thing.
Must Have Appz:
- Django Extensions: This application gives you a ton of great stuff for your Django app including runserver_plus, shell_plus, and a bunch of other things. runserver_plus gives you the ability to have a shell in browser with the current context if debug is turned on. How awesome! Theres a lot of other bells and whistles in django-extensions which you can read about here.
- SORL: This application allows you to use a template tag or model field to dynamically create thumbnail images. It will automatically resize and crop images (including TIF files, PDFs, PNGs, etc…). One thing with PNGs is that it won’t obey alpha transparency. For PNG alpha transparency layers, check this fix out.
- Filebrowser: This sweet app puts a filebrowser into the django admin which you can then use in TinyMCE or another rich text editor.
- Chunks: This app allows you to have a template tag with which you can define keys for short (or long) text chunks in your templates. Then in your django admin, you can define these keys, and have an instant place in the CMS to update these text chunks. Neat right?
- Registration: This baby takes care of all of your registration needs. It uses django’s built in auth backend, but has all of the views and urls written so that your applications user registration is practically plug and play. Now all you have to do is define the templates.
INSTALLED_APPS = (
# ...
# Third Party Django Applications
'django_extensions',
'sorl.thumbnail',
'filebrowser',
'chunks',
'registration',
# Project Applications
'app_name',
)
Template Tags
This guy is pretty important. The DRY principle states very plainly, “don’t repeat yourself”. Seriously, stop repeating yourself. I pump all of my template tags into this tuple here, and then in a bootstrap.py (could be your __init__.py, doesn’t matter) I loop through an add these template tags to my built ins. Here’s a snippet with that code if you want to read up more on that. This allows me to just use my favorite template tags within templates without having to load them at the top of each template.
TEMPLATE_TAGS = (
'sorl.thumbnail.templatetags.thumbnail',
'chunks.templatetags.chunks',
)
Local Settings
Finally, this is at the bottom of each of my settings.py files. This ensures that I’m using the local_settings.py file for all of my local resolution settings respective to that machine. So for instance, in production, I may be using a mySQL database, whereas on my local machine, I prefer to use a sqlite file.
try:
from local_settings import *
except ImportError:
pass
Once again, here’s the whole file: http://gist.github.com/214361
If you have any questions, or suggestions on how to make this file better, please post them in the comments! Thank you!
Update: Switched snippet links from dpaste to git hub so that they’re archived.
Tags: Django, Programming, Python

Sounds awesome!
I prefer to use bash variables to identify prod/dev/qa etc. and then read them off in the settings.py and have big if/else blocks for environment specific settings. Rest is common.
That sounds like a good idea, do you have an example of how it’d look? I’m assuming you’d have to input your variables with the runserver command.
No… nothing to give runserver. Use os.environ to get the values and then some if/else blocks works just fine:
ENV = os.environ['ENV']
if ENV == ‘dev’:
IS_DEV = True
DEBUG = True
LOG_LEVEL = logging.DEBUG
.
.
.
.
Ah, very nice. Thanks!
You’ve touched on it, but I like to create a ‘path’ function:
import os
ROOT = os.path.abspath(os.path.dirname(__file__))
# get paths relative to settings.py
path = lambda x: os.path.join(ROOT, x)
Which I can then use all over the place:
DATABASE_NAME=path(‘db.sqlite3′)
TEMPLATE_DIRS=path(‘templates/’)
… etc …
Hi,
I have a few suggestions, but first of all I want to say that I like your approach, it’s much better than many others I’ve seen on the past.
1. I’m pretty sure django does the same as your “Template Directories” trick on the fly for you already.
2. I don’t think it’s a good idea make your repository ignore local_settings.py, I’d rather put it on the Python path somewhere else.
That’s all
Hey David,
I’m interested in why you suggest that. All that my local_settings.py file has is some DB settings. It doesn’t need to be version controlled. It only consists of four lines.
There are some good tips here, but I noticed your links to Google Code are all messed up. I’m not quite sure how, but it looks like WordPress switched code.google.com to be pre.google.com (I’m guessing something with the code and pre HTML tags).
Also, for template directories you don’t need to specify these out if you name them like you do. Django automatically looks for a directory called templates in all installed apps. Check out django.template.loaders.app_directories.load_template_source in the docs http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
To get it to work on a windows box add:
.replace(‘\\’,'/’)
to all the settings that has anything with a path in it
Thanks for a great writeup. One thing: your link to the django-command-extensions app is broken — change ‘pre’ to ‘code’ in the href
Shameless plug: Djangy.com is a new heroku clone for django. it allows you to push your apps and have an instant deployment onto the servers. if you’re interested, i can secure you a private beta invitation.
again, good blog post. thanks!