WDTutorials.com Become A Professional
Software Developer.

Django - ImageKit Tutorial (Python)

How to create thumbnails using django-imagekit.

Updated May 2, 2024

Table of contents

You will learn

  • How to upload and display images.
  • How to automatically generate image thumbnails.

Install dependencies

pip install pillow django-imagekit

Settings

Edit settings.py and add these lines to it:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'imagekit', # here
    'blog'
]

# here
MEDIA_URL = 'media/' 
MEDIA_ROOT = BASE_DIR / 'media'
  • MEDIA_URL is the URL prefix. The images will be served as follows: mysite.com/media/images/image.png.
  • MEDIA_ROOT is the physical location in the file system where the images are stored.

Enable media file serving

Edit urls.py and add these lines to it:

from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static # here
from mysite import settings # here

urlpatterns = [
    path('blog/', include('blog.urls')),
    path('admin/', admin.site.urls),
]

# here:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  • static() function serves media files during development. In production you would typically use something like Nginx to serve the files.

Update a model

Add these lines to a model:

from django.db import models
from django.urls import reverse
from imagekit.models import ImageSpecField # here
from pilkit.processors import Thumbnail # here


class Post(models.Model):
    title = models.CharField(max_length=255, blank=False, default='')
    body = models.TextField(blank=False, default='')
    slug = models.SlugField(max_length=255, blank=False, unique=True)
    image = models.ImageField(upload_to='images', default='') # here
    # here:
    image_thumbnail = ImageSpecField(source='image',
                                     processors=[Thumbnail(200, 100)],
                                     format='JPEG',
                                     options={'quality': 60})

    def get_absolute_url(self):
        return reverse('blog:post_detail', args=[self.slug])
        
    def __str__(self):
        return self.title
  • ImageField allows users to upload images. In this case, we store the images in the media folder at the project root (make sure to add the media folder to your gitignore file). You could also store the images in a cloud storage, such as Amazon S3.

  • ImageSpecField is used for generating thumbnails from the original image. Thumbnails are generated (and cached) the first time they are requested, such as when you visit a page where the image_thumbnail field is used.

Run migrations:

python manage.py makemigrations
python manage.py migrate

Upload an image

Visit /admin/ and upload an image:

Here is an image for you.

Displaying the images

Add these lines to a template:

<div class="post">
    <h1>{{ post.title }}</h1>
    <div class="body">{{ post.body }}</div>
    <!-- start -->
    {% if post.image %}
        <img src="{{ post.image_thumbnail.url }}">
        <img src="{{ post.image.url }}">
    {% endif %}
    <!-- end -->
</div>

You should see the thumbnail and the original image below it:

  • The thumbnail is served from an URL such as this: media/CACHE/images/images/example/2cd5fe32037b2794931412306315942b.jpg
  • The original image is served from media/images/example.jpg.

Closing remarks

You can dramatically decrease the size of images with this library. For example, in this case, the thumbnail is only 4.5kB, while the original is 238 kB! This matters if you have a lot of images on your page.

Troubleshooting : AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'?

Are you encountering the following error: AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'? Try downgrading (or upgrading) Pillow:

pip uninstall pillow
pip install Pillow==9.5.0

Leave a comment

You can use Markdown to format your comment.