Django Blog Images

May 12, 2010

I wanted a nice way to be able to upload images for display in a blog entry. I'm already using Markdown for the blog syntax, so I was looking for a way to integrate with this too.

Le Morne, Mauritius

Mauritius Rock

Model

I added a new model to the blog application, to hold the images:

class BlogEntryImage(models.Model):
    """
    An image associated with a blog entry
    """       
    last_modified = models.DateTimeField(default=datetime.now,editable=False)
    created = models.DateTimeField(default=datetime.now,editable=False)
    title = models.CharField(max_length=20)
    image = models.ImageField(upload_to='images/%Y/%m/%d', height_field='height', width_field='width')
    width = models.IntegerField(editable=False)
    height = models.IntegerField(editable=False)
    blog_entry = models.ForeignKey(BlogEntry)

Admin

I then changed the admin settings, so this was an tabular inline on the blog edit page:

class BlogImageInline(admin.TabularInline):
    model = BlogEntryImage

class BlogEntryAdmin(VersionAdmin):
    inlines = [BlogImageInline,]

 admin.site.register(BlogEntry, BlogEntryAdmin)

Blog Save

The markdown code is converted to HTML at the time the blog entry is saved. I extended this to look through the attached images and replace ![Image Title] with the required markdown syntax, which is ![Image Title](/path/to/jpg).

def save(self):
    self.last_modified = datetime.now()
    if self.process_hyperlinks:
        lBody = urlize_string(self.body)
    else:
        lBody = self.body
    for image in self.blogentryimage_set.all():
        lImageTag = '![%s]' % image.title
        lImageReplace = '![%s](%s)' % (image.title, image.image.url)
        lBody = lBody.replace(lImageTag, lImageReplace)
    self.body_html = markdown(lBody, ['codehilite'])
    super(BlogEntry, self).save()

This does assume that the BlogEntryImage instances have been saved before the blog entry, so you might have to save twice to pick them up.

Tags: django image markdown