E-Scribe News : a programmer’s blog

About Me

PBX I'm Paul Bissex, and e-scribe.com is my consulting business. I build web applications using open source software, especially Django. I teach photographers web design and professional skills. 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. Feel free to email me.

Book

Python Web Development with Django I'm co-author of "Python Web Development with Django", an excellent guide to my favorite web framework. Its strong points include an introduction to Python, and better coverage of Django 1.0 than nearly anybody else. Published by Addison-Wesley, it is available from Amazon and your favorite technical bookstore as well.

Colophon

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.

Pile o'Tags

Stuff I Use

Akismet, del.icio.us, Django, dpaste.com, Emacs, FreeBSD, Freenode, jQuery, LaunchBar, MacPorts, Markdown, Mercurial, OS X, Postfix, Python, SQLite, Subversion, TextMate, Trac, Ubuntu Linux, wmii

Spam Report

At least 67551 pieces of comment spam killed since January 2008, mostly via Akismet.

Moving the blog to Django

The long-awaited (by me) conversion of this blog to Django is underway. After a couple hours' work I have a full set of models and a functioning admin, and working index and detail views of postings and comments. Searching, posting comments, and tags are the major pieces remaining. Because of my busy schedule I'll only be able to work on it in fits and starts, but I expect the total labor in the end to be about five hours.

I'm curious what the line count of the final product will be. The PHP version, excluding my general-purpose admin class and third-party stuff like Markdown, is about 1000 lines. I'm guessing the linecount of the Django version will be somewhere around a third of that. It's great to see the code melt away, even when it's just single lines getting shorter. For example, this:

$comments = $blog->query("SELECT comments.name, comments.id, posts.title, posts.id FROM
comments, posts WHERE posts.id=comments.post_ref ORDER BY comments.timestamp DESC 
LIMIT $RECENT_COMMENT_LIMIT");

becomes this:

comments = Comment.objects.all().order_by('-timestamp')[:RECENT_COMMENT_LIMIT]

When I started working with Django, one thing I missed from my own PHP admin code was automatic introspection. For example, in my system, this code produces a complete, functioning admin page for editing comments:

include "DB_Edit.class.php";
$admin = new DB_Edit ($DB_PATH, "comments");
$admin->set_summary_cols ("name", "post_ref", "timestamp");  // like Admin.list_display
$admin->set_input_type ("comment", "textarea");
$admin->catch_requests("capture");
$body = $admin->html;
print $body;  // typically you would include() a template instead of printing

DB_Edit basically assumes everything is input type="text" unless told otherwise. Not a bad default for most apps, and it makes getting going very quick. But over time, because there's no single definition of the model (except for the database itself), model logic ends up getting scattered throughout the code. Django is keeping things much cleaner.

Yay Django for using regex-based URL patterns that easily replace mod_rewrite rules. Yay me for having no public *.php URLs in the current version.

This is a rewrite, not a port. Instead of going through my PHP codebase line by line, I'm building up the new version component by component. With the models in place, there's not much need to refer to the PHP code at all.

More news as it happens.

Monday, April 10th, 2006
+ + + +
12 comments

Comment from Matisse Enzer , later that day

I especially like the before-and-after comparison - that sort fo thing helps me understand code better than a lot of explanations.

Comment from Dagur , later that day

comments = Comment.objects.all().order_by('-timestamp')[:RECENT_COMMENT_LIMIT]

Just wondering, isn't it possible to limit the number of results without fetching all the objects and slicing?

Comment from Paul , later that day

It's not only possible, but it's already happening in that example -- the db lookups are lazy. See the [query.py source][1] for details if you're curious.

[1]: http://code.djangoproject.com/browser/django/branches/magic-removal/django/db/models/query.py#L96

Comment from Adrian Holovaty , later that day

Note you don't need the all() there, although it works either way.

Old:

Comment.objects.all().order_by('-timestamp')

Better:

Comment.objects.order_by('-timestamp')

You only need the all() if you're not applying any filters.

Comment from Paul , later that day

Thanks, not sure how I made that error. I have the M-R query examples taped to my desk!

Got tags working today. Getting closer...

Comment from dp_wiz , 1 day later

> When I started working with Django, one thing I missed from my own PHP admin code was automatic introspection.

Duh! Django's internal admin stuff is really awesome.

Comment from Paul , 1 day later

Indeed it is. But it doesn't to table introspection on the fly. As I said, Django's approach is ultimately cleaner.

Comment from dp_wiz , 1 day later

you can take introspection code from django-admin.

Comment from Paul , 2 days later

Perhaps I'm not being clear. I don't want to change the way Django works!

Comment from Andrew , 3 days later

Will your code be available? I'm curious as to how you're doing tagging. I've implemented a very craptastic way to do it for my blog (though i haven't put it up yet), but really don't like my solution to it. Glad to see you moving this to django.

Comment from Paul , 4 days later

Funny you should mention tagging -- that's the one part of my original model that I've decided really needs to change. Django makes it so easy to do many-to-many relations that I can do it right, instead of carrying over the (surprisingly functional) space-delimited-text hack that I'm using now. Having a real tag model will make it easier to reimplement the current features and to add new ones.

I may use [Hugo's tagging code][1].

I do plan to release the source, but I'm so busy with work that the whole thing's going in slow-motion right now.

[1]: https://simon.bofh.ms/cgi-bin/trac-django-projects.cgi/wiki/AbstractTagging

Comment from Matthias , 4 weeks later

Yay, an open-source Django blog! Can't wait.

Post a comment

Thanks for reading! Please note: Your comment will not appear until approved, which may take a few hours or more. Spammers will be torpedoed.


(Will not be shared)

(Optional)