Notes on my new Django setup

My personal record of using revision control for source code has been pretty spotty. Today I took steps toward fixing that by working out a system for managing my Django projects. I wanted revision control (Subversion), I wanted Django’s “runserver” for development and mod_python for deployment, and I didn’t want it to be a pain.

Some highlights of the process:

  • I used my pastebin site as the test mule. I checked in the current live site’s source code, created “trunk”, “tags”, and “branches” directories per the Subversion manual, and checked out a copy of the trunk into a staging directory.

  • I used svn propedit svn:ignore to keep the project’s SQLite database file out of the repository. Via my ~/subversion/config file I also ignore few other things such as .pyc files, just so that svn status checks aren’t littered with question marks on those files.

  • I created a simple script that sets $PYTHONPATH (so that imports like from pasteproject import settings find the staging version, not my deployed version!) and starts the Django development server.

  • Tricky Django thing #1: I use the conditional URLconf trick in order to correctly serve media files when using the development server. The docs on this trick go on to say; “the catch here is that you’ll have to remember to set DEBUG=False in your production settings file.” Which brings me to…

  • Tricky Django thing #2: Modular settings. The first line of is: from pasteproject.settings_local import DEBUG, TEMPLATE_DEBUG, PROJECT_BASE. The file is not under version control, and is of course different for the development and deployment versions. It’s only two lines; the first line sets DEBUG and TEMPLATE_DEBUG to True (development) or False (deployment); the custom setting PROJECT_BASE is used to locate the correct SQLite database file and the media files.

All this was a bit of work, but what it saves me in time and worry will more than make up for that.

Update: And of course it wouldn’t be an upgrade if I didn’t break something – the pastebin’s SQLite database permissions got set to read-only, which I fixed just now.

Joshua Bloom commented on Wed Apr 25 17:50:45 2007:

For my Django work I’m usually developing on a windows Desktop or Laptop. When my stuff gets deployed it goes up to our linux servers.

In my files I do something like this:

if os == linux: production = True

if production: #Change where the SITE_MEDIA is being served from.
    urlpatterns += patterns('',
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/...'}),
    urlpatterns += patterns('',
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': 'C:/...'}),

Paul commented on Wed Apr 25 18:39:51 2007:

Cool! I love seeing the recipes people come up with to handle deployment.

My current setup is a little different now. I no longer use a; I put a conditional in itself sort of like your if os... line to control DEBUG etc. I have a setting called PROJECT_BASE which is used by MEDIA_ROOT and other settings that reference the filesystem.

I no longer need the conditional URLconf trick that I linked to; if the site is running on Apache (as opposed to Django’s runserver), a SetHandler None directive keeps Django from seeing any requests for static media.

I hope that we can start to incorporate some of these patterns (suitably generalized) into the framework itself as time goes on.