Updated Django image thumbnailer

I've actually gotten a few emails about my django thumbnailer code recently, turns out a search for "django image thumbnails" now has me on the front page of listings from google.

Anyway, i actually use an updated version from my previous post which i've included here:

import os
import Image
from django import template
from django.conf import settings

register = template.Library()

ERROR_IMG = settings.DEFAULT_ERROR_IMAGE

def create_thumbnail_image_file(file, width, height):
    """ Create a thumbnail image and return the path """
    if not file:
        return ERROR_IMG
    
    basename, format = file.rsplit('.', 1)
    thumb = basename + '_' + str(width) + 'x' + str(height) + '.' + format
    thumb_filename = os.path.join(settings.MEDIA_ROOT, thumb)
    thumb_url = os.path.join(settings.MEDIA_URL, thumb)

    filename = os.path.join(settings.MEDIA_ROOT, file)
    if os.path.exists(thumb_filename):
        if os.path.getmtime(thumb_filename) < os.path.getmtime(filename):
            os.unlink(thumb_filename)
        else:
            return thumb_url
    
    image = Image.open(filename)
    image.thumbnail([width, height], Image.ANTIALIAS)
    image.save(thumb_filename, image.format)
    return thumb_url

class ThumbnailerNode(template.Node):
    def __init__(self, image, width, height):
        self.image = image
        self.width = width
        self.height = height
    
    def render(self, context):
        try:
            actual_image = template.resolve_variable(self.image, context)
            return create_thumbnail_image_file(actual_image, self.width, self.height)
        except template.VariableDoesNotExist:
            return ERROR_IMG
          
@register.tag(name="thumbnail")
def thumbnail(parser, token):
    try:
        tag_name, image, width, height = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, " %r tag requires exactly 3 arguments" % token.contents[0]
    return ThumbnailerNode(image, int(width), int(height))
<

I think calling this from a template is much nicer than the old code using a filter. You can now just insert:

{% thumbnail <image_object> width height %}