Yet Another Django Blog

To help me learn Django, I decided to build a blog. It was surprisingly easy. This article walks through my initial version of the site.

Update 1/14/2008: While this site is no longer built using Django, I thought I'd keep my Django-related posts up here as I've gotten a decent amount of feedback from people doing similar projects.

I've recently cutover from WordPress to a new blog which I developed using Django. I've been using Django at work for the past month and as I've gotten more familiar with it, I decided building a completely new blog would actually be fun and fairly simple. Besides, I've read about a few other people who have done the same thing and they say the hardest part was converting over their old blog entries. That should be cake for me as I only have a handful of posts to worry about!

If you haven't heard of it yet, Django is a framework for building web applications written in Python. It's an open-source project that spun out of an online news organization and thus has its roots in CMS applications. But it has now grown to support many other kinds of web applications. I stumbled onto Django when I was looking for a better way to build software after using C#/.NET and ASP.NET for the last two years. That led me to Python and I quickly found myself leaving C# behind with no regrets. Once I was sold on Python, I started looking at the "right" way to build web apps in Python. While there really isn't an answer to that question, Django comes pretty darn close.

Building the Blog

After reading the posts above about other Django-based blogs, I sat down to start my own. It took me about an hour to get a first cut of a working blog together, which I think is great, but some people seem fixated on the 15- or 20-minute project. I was basing some of my design on other people's older code base which changed considerably with the "magic-removal" relase so I had to convert things over (using the sophisticated engineering technigue of: refresh the browser, read the error message, fix the code, rinse, repeat).

I started with these fairly basic models for a Tag and a Post which gives you useful enough models for a surprsingly workable blog.

class Tag(models.Model):
    slug = models.SlugField(prepopulate_from=('title',), primary_key=True)
    title = models.CharField(maxlength=30)
    description = models.TextField(help_text='Short summary of this tag')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/blog/tag/%s/" % self.slug

    class Admin:
        list_display = ('slug', 'title',)
        search_fields = ('title', 'description',)

    class Meta:
        ordering = ('title',)

A Tag is just really just a unique string used to categorize posts. In hindsight, I could have made this even simpler as I'm really just using a Tag's slug field. A Post is the model that really makes it a blog. Its also pretty simple, with the obvious fields: title, date and body, plus a the many-to-many tags relationship. It also has a slug field which is like a human-readable key to make it easier to refer to an object by a friendly name rather then a number.

class Post(models.Model):
    slug = models.SlugField(prepopulate_from=('title',), primary_key=True)
    tags = models.ManyToManyField(Tag)
    title = models.CharField(maxlength=80)
    date = models.DateTimeField(auto_now_add=True)
    body = models.TextField()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/blog/%s/%s/" % (self.date.strftime("%Y/%m/%d").lower(),
                                 self.slug)

    class Admin:
        list_display = ('slug', 'title', 'date',)
        search_fields = ('title', 'body',)
        date_hierarchy = 'date'

    class Meta:
        get_latest_by = 'date'
        ordering = ('-date',)

Now that I'm a little more familiar with the problem, I could probably start from scratch and do it again in under 30 minutes, but why? In fact, I think someone should make a video of a real development session with all the typical mistakes and error messages, along with a voice over of how the user figured out the problem from the errors. Now that would be useful.

After getting the basic features done, I started working on the little tweaks that would make it more polished and easy to use. Some of these things came very easy but others were a little trickier. I'll post my comments on some of these features in the near futrue, as the information might be useful to others.

|