Django SkyThumbnails Tutorial

SkyThumbnails – a Django Library – allows the easy creation and implementation of variously sized images for any project. SkyThumbnails makes designing standard sizes simple, allows uploading of raw images, and quickens the propigation of images across your website. The complete codebase can be found on GitHub, as can the sample project, which we reference in this tutorial.


To properly set up your project, we need to tweak a few settings. First, add SkyThumbnails to the app list like so:


We also need to specify when to generate the thumbnails. When you set IF DELAYED_GENERATION to false – as the user uploads images – SkyThumbnails generates thumbnails the first time the image uploads. This means a quicker load the first time the system loads an image, but this can use more space than if you set DELAYED_GENERATION to true. Therefore, it may make more sense to set DELAYED_GENERATION to true, thus generating thumbnails on demand, rather than by default. If the browser requestes an image in a size not yet requested, SkyThumbnails creates one on the spot. We can also specify where to put the thumbnails. By default, this directory maintains its position on the same level as the full-size images in the uploads folder.


Image Models

Time to define what our images will look like in the system. Let's start by giving them a title and a description. We'll use "Photo" as the name of our class for clarity.

class Photo(models.Model):
    title = models.CharField(
        max_length = 200,
        help_text = 'Title of the image',
    description = models.CharField(
        max_length = 500,
        help_text = 'Description of the image',

Now for the cool part. Define an attribute to represent the image, which is an instance of EnhancedImageField. As we can see below, it should have an upload_to directory, which should be some sort of media directory (i.e., mediafiles > uploads). SkyThumbnails stores thumbnails for these images in this directory, the same directory we earlier specified in the settings. The EnhancedImageField uploads the image at the size specified in process_source. Should the size differ from the actual size of the image, the SkyThumbnails crops the image to the specified dimensions. We also specify thumbnail sizes in a thumbnails attribute within image. To do this, we use a dictionary with keys that name the image sizes. We can set as many or as few sizes as our project requires.

class Photo(models.Model):
    title = models.CharField( … )
    description = models.CharField( … )

    image = EnhancedImageField(
        verbose_name='Image of various sizes',
        upload_to = 'uploads',

        # (width, height) of original image
        process_source = dict(size=(300,300)),
        thumbnails = {
            # (width, height) of smaller images
            'medium': dict(size=(115,115)),
            'small': dict(size=(80,80)),
            'icon': dict(size=(30,30)),

Uploading Images

Now to upload some images to play with. Our should look something like this:

from django.contrib import admin
from photos.models import *

class PhotoAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'image'), PhotoAdmin)

First, we do the standard django.contrib admin import. We also need to import the model we just created. Our app is called photos, so we import everything from photos.models. PhotoAdmin defines our admin view, and we chose to list the title, description, and image attributes there for all privileged users to see. Register the Model/Admin Class, and we're good to go.

The Django Admin should look something like the screenshot above, though without any photos yet. Let's hit the "Add photo" button, enter the information, and save our file. Back in the admin list of photos, verify that the photos were saved where specified.

Bringing the Images into View

To demonstrate populating the DOM with our sweet new images, we will use Jinja syntax. Here, we check to make sure an image exists, we do this by calling object.image. Then, we inject the title with object.title. To get the full-size image, use object_name.image_attribute.url. Similarly, use the following to get the images; object_name.image_attribute.size_name.url. The sample below should make this clear.

{% if object.image %}
    <h1>{{ object.title }}</h1>
    <img src="{{object.image.url}}" alt="Full" />
    <img src="{{object.image.medium.url}}" alt="Medium" />
    <img src="{{object.image.small.url}}" alt="Small" />
    <img src="{{object.image.icon.url}}" alt="Icon" />
{% endif %}

We can also use photo.image.url, so do what makes sense. Here's what it looks like in a table:

Having demonstrated the ugliest possible implementation of this library, we can move past the basics; we can imagine ourselves easily building social profile pages, churning out avatars for comment threads, and many other possible use cases for SkyThumbnails. The library also contains other options not explored here, such as sharpening, upscaling, and changing the image format of our thumbnails.

comments powered by Disqus