I'm Paul Bissex. I build web applications using open source software, especially Django. In the '90s I did graphic design for newspapers and magazines. Then I wrote technology commentary and reviews for Wired, Salon.com, Chicago Tribune, and lots of little places you've never heard of. Then I taught photographers how to create good websites. I co-wrote a book along the way. Now I am helping turn a giant media corporation into a digital enterprise. Feel free to email me.
I'm co-author of "Python Web Development with Django", an excellent guide to my favorite web framework. Published by Addison-Wesley, it is available from Amazon and your favorite technical bookstore as well.
Built using Django, served by Apache and mod_wsgi. The database is SQLite. The operating system is FreeBSD, on a VPS hosted at Johncompanies.com. Comment-spam protection by Akismet. Vintage topo imagery from the Maptech archive. The markup engine is Markdown.
Akismet, bitbucket, del.icio.us, Django, Emacs, FreeBSD, Git, jQuery, LaunchBar, Markdown, Mercurial, OS X, Postfix, Python, Review Board, S3, SQLite, TextMate, Ubuntu Linux
At least 184593 pieces of comment spam killed since January 2008, mostly via Akismet.
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 runserver.sh 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 settings.py is: from pasteproject.settings_local import DEBUG, TEMPLATE_DEBUG, PROJECT_BASE. The file settings_local.py 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.
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 settings_local.py; I put a conditional in settings.py 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.
Thanks for reading! Please note: Your comment will not appear until approved, which may take a few hours or more. Spammers will be torpedoed.
Booktools
2 comments
A different kind of URL shortener
4 comments
The syncbox
2 comments
Branching and merging in real life
8 comments
Marko Knöbl
Understanding tuples vs. lists in Python
2 days ago
Marko Knöbl
Understanding tuples vs. lists in Python
3 days ago
Matt Stevens
Understanding tuples vs. lists in Python
71 days ago
Chirag
Understanding tuples vs. lists in Python
80 days ago
B.J. Justice
Trying to send eBay a message?
106 days ago
Copyright 2013
by Paul Bissex
and E-Scribe New Media
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 urls.py files I do something like this: