Django - ImageKit Tutorial (Python)
How to create thumbnails using django-imagekit.
Updated Aug 24, 2023

Versions

Tested with these packages:

  • Django==4.2.4
  • django-imagekit==4.1.0

Troubleshooting

Are you encountering the following error: AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'?.

Try downgrading Pillow:

pip uninstall pillow
pip install Pillow==9.5.0

Setup Project

Oneliner (Windows):

mkdir mysite && cd mysite && python -m venv venv && venv\Scripts\activate.bat && pip install django pillow django-imagekit && django-admin startproject mysite . && python manage.py migrate && set "DJANGO_SUPERUSER_PASSWORD=admin" && python manage.py createsuperuser --noinput --username admin --email admin@example.org && python manage.py startapp myapp && python manage.py runserver

Oneliner (macOS, Linux):

mkdir mysite && cd mysite && python -m venv venv && source venv/bin/activate && pip install django pillow django-imagekit && django-admin startproject mysite . && python manage.py migrate && export DJANGO_SUPERUSER_PASSWORD=admin && python manage.py createsuperuser --noinput --username admin --email admin@example.org && python manage.py startapp myapp && python manage.py runserver

OR do it manually:

mkdir mysite
cd mysite
python3 -m venv venv
venv\Scripts\activate.bat (Windows)
source venv/bin/activate (macOS, Linux)
pip install django pillow django-imagekit
django-admin startproject mysite .
python manage.py migrate
python manage.py createsuperuser
python manage.py startapp myapp
python manage.py runserver

Edit mysite/settings.py

Add these lines to the project settings file:


import os # IMPORT THIS

INSTALLED_APPS = [
    # START
    'myapp.apps.MyappConfig',
    'imagekit',
    # END
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# START
MEDIA_URL = '/media/' 
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# END

Edit myapp/models.py

Create the following model. This allows us to upload an image and automatically generate 2 thumbnails for it:

from django.db import models
from imagekit.models import ImageSpecField
from pilkit.processors import Thumbnail


class Post(models.Model):
    image = models.ImageField(upload_to='images')
    image_medium = ImageSpecField(source='image',
                                  processors=[Thumbnail(200, 100)],
                                  format='JPEG',
                                  options={'quality': 60})
    image_small = ImageSpecField(source='image',
                                 processors=[Thumbnail(100, 50)],
                                 format='JPEG',
                                 options={'quality': 60})
    slug = models.SlugField(max_length=255, unique=True)

Edit myapp/admin.py

Register the Post model so that we can add content using the admin app:

from django.contrib import admin
from . import models


admin.site.register(models.Post)

Run migrations

Create a database table for the Post model:

python manage.py makemigrations
python manage.py migrate

Edit mysite/urls.py

Add these lines to the project urls.py file:

from django.contrib import admin
from django.urls import path

# START
from django.conf.urls.static import static
from django.conf import settings
from myapp.views import PostDetailView
# END

urlpatterns = [
    # START
    path('blog/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
    # END
    path('admin/', admin.site.urls),
    # USE THE STATIC() FUNCTION:
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

The static() function allows us to serve media files (the uploaded and resized images) during development.

Edit myapp/views.py

Create a view for blog posts:

from django.views.generic import DetailView
from myapp.models import Post


class PostDetailView(DetailView):
    model = Post

PostDetailView uses a template named post_detail.html automatically.

Create myapp/templates/myapp/post_detail.html

Create a file called post_detail.html in the myapp/templates/myapp directory (you have to create the templates folder). Add these lines to it:

{% if post.image %}
    <img src="{{ post.image.url }}">
    <img src="{{ post.image_medium.url }}">
    <img src="{{ post.image_small.url }}">
{% endif %}

Create content and visit the blog detail page

Visit /admin/ to create a new blog post:

Visit /blog/django-tutorial/ and you should see the original image and 2 thumbnails:

Thumbnails are generated when you first visit the detail page.

The original image is served from the media/static folder:

media/static/images/05.jpg

The thumbnails are served from the media/CACHE folder:

media/CACHE/images/images/21da-JZerh...jpg