The Tsonny Blog

My Django redesign October 24, 2006

My Django redesign

It's been a long while since I last updated my old page. Reason was that it was cumbersome even to change small things, since it did not feature a web interface, but required me to login via SSH.

All in all, it was a technically cool solution but rather impractical from a user's point of view. Now, since Django, the Python Web Framework, is getting so much attention recently, I gave it a try at redesigning my old page. In fact, I didn't just want to redesign, but extend it with a blog application.

I started diving into Django without having any idea of Python at all (I do however have several years of experience in PHP and Perl/mod_perl and other MVC web frameworks).

How it is done

Django installation and configuration is pretty well-covered on the Django project site and I won't repeat it here again. I'll assume you've successfully installed Django and created your own project.

My page has a number of sections (top navigation bar), which are all based on Django's internal django.contrib.flatpages. The blog section, on the other hand, is a custom application. All it needs is the following model:

from django.db import models

class Tag(models.Model):
	slug = models.SlugField(prepopulate_from=('title',))
	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',)

class Post(models.Model):
	slug = models.SlugField(prepopulate_from=('title',), help_text='Automatically built from the title.'
	)
	assoc_tags = models.ManyToManyField(Tag)
	title = models.CharField(maxlength=80)
	date = models.DateTimeField(auto_now_add=True)
	body = models.TextField()
	image = models.ImageField(
		'Attach Image',
		upload_to='blog',
		blank=True
	)
	def __str__(self):
		return self.title
	
	def get_absolute_url(self):
		return "/blog/%s/%s/" % (self.date.strftime("%Y/%b/%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',)

To display the tag list on the right of this page, I used a simple template tag like this:

from django import template
from tsonny.blog.models import Tag

class TagListNode(template.Node):
	def __init__(self, varname):
		self.varname = varname

	def render(self, context):
		context[self.varname] = Tag.objects.all()
		return ''

def do_get_tag_list(parser, token):
    """
    {% get_tag_list as tag_list %}
    """
    bits = token.contents.split()
    if len(bits) != 3:
        raise template.TemplateSyntaxError, "'%s' tag takes two arguments" % bits[0]
    if bits[1] != "as":
        raise template.TemplateSyntaxError, "First argument to '%s' tag must be 'as'" % bits[0]
    return TagListNode(bits[2])

register = template.Library()
register.tag('get_tag_list', do_get_tag_list)

To include the "latest news" from other website's RSS feeds, I simply took the aggregator code from djangoproject.com (it's in the Trac repository) and modified it a bit.

To make life easier, the interested reader may also want to download the complete code, ready to use (but without templates, of course).

Comments

No comments posted yet. You could be the first!


Comments have been disabled for this post.