WDTUTORIALS
menu
Django - The Easy Way Django - The Easy Way
Samuli Natri 2018.03.08
Samuli Natri is a software developer who enjoys programming games and web applications. He attended Helsinki University Of Technology (Computer Science) and Helsinki University (Social Sciences).

Django - Thumbnails With ImageKit

Tutorial on how to generate thumbnails from bigger images.

Installation

pip install pillow django-imagekit

Open settings.py and add imagekit to the INSTALLED_APPS list:

INSTALLED_APPS = [
  ...
    'imagekit',
]

Define MEDIA_URL and MEDIA_ROOT.

# Path from where the images are served (like mysite.com/media/post_images/01.png)
MEDIA_URL = '/media/'
# Physical path to the images
MEDIA_ROOT = 'media/'

In this case I have the MEDIA_ROOT in the site root next to the site apps. In production sites this could be something like /home/mysite/media/.

To serve user-uploaded media files during development (in debug mode), use the static function in your urls.py file:

from django.contrib import admin
from django.conf.urls.static import static # < this

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('base.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # < this

Add Thumbnail Fields

Open the models.py file that has an image field.

Let's use ImageSpecField to create thumbnails:

from imagekit.models import ImageSpecField # < import this
from imagekit.processors import ResizeToFill # < import this

...
image = models.ImageField(upload_to="post_images") # Regular image field
image_thumbnail = ImageSpecField(source='image',
                                 processors=[ResizeToFill(100, 50)],
                                 format='JPEG',
                                 options={'quality': 60})

 

Name Description
source Source field. We want to create thumbnails from the image field images.
ResizeToFill Resizes and crops the image to the specified width and height.
JPEG Image is stored as JPEG.
60 Compression quality.

Use the thumbnail path in a template to generate the thumbnail:

{{ post.image_thumbnail.url }}

And example with the original image:

  <div class="post__image post__item">
    <img class="post__image__img" src="/media/{{ post.image }}">
  </div>
  <div class="post__thumbnail post__item">
    <img class="post__thumbnail__img" src="{{ post.image_thumbnail.url }}">
  </div>

So now the original image is stored in:

media/post_images/01.png

And its thumbnail is stored in:

media/CACHE/images/post_images/01/23ds..cd1.jpg

So in the CACHE folder there are now folders named with the image (01 in this case) and inside that folder is the generated image.

Add Additional Thumbnails With Different Sizes

You can add more image fields with different configurations:

image_thumbnail_2 = ImageSpecField(source='image',
                                   processors=[ResizeToFill(200, 100)],
                                   format='JPEG',
                                   options={'quality': 60})
  ...
  <div class="post__thumbnail__2 post__item">
    <img class="post__thumbnail__2__img" src="{{ post.image_thumbnail_2.url }}">
  </div>
  ...

Now you can see the second thumbnail stored in the same 01 folder:

media/CACHE/images/post_images/01/fda..ad1.jpg

Process The Original Image

If you don't want to store the original image, replace the image field with ProcessedImageField:

from imagekit.models import ImageSpecField, ProcessedImageField

    # image = models.ImageField(upload_to="post_images")

    image = ProcessedImageField(upload_to='post_images',
                                processors=[ResizeToFill(400, 200)],
                                format='JPEG',
                                options={'quality': 60})

The original image is now stored in the same place as before, but it is processed to smaller size:

media/post_images/01.png

You can do a lot more with the package like rotate the images and create black and white photos, so check out the official documentation for more info.