Thumbnails for Django. You write the size in the template, or ask for it in Python, and sorl-thumbnail makes the thumbnail on first use with Pillow, libvips or ImageMagick, saves it on your media storage and remembers it in a key-value store, so later renders cost no image work and no storage request.
- Website, with an example gallery for every image engine: https://mariocesar.github.io/sorl-thumbnail/
- Documentation: https://sorl-thumbnail.readthedocs.io/
Install sorl-thumbnail with Pillow:
pip install "sorl-thumbnail[pil]"
Add 'sorl.thumbnail' to INSTALLED_APPS:
INSTALLED_APPS = [
...
'sorl.thumbnail',
]
and create its table:
python manage.py migrate
Then, in a template:
{% load thumbnail %}
{% thumbnail item.image "100x100" crop="center" as im %}
<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
{% endthumbnail %}
item.image can be an ImageField, a path in your media storage or the
URL of an image. The same from Python:
from sorl.thumbnail import get_thumbnail im = get_thumbnail(item.image, '100x100', crop='center', quality=99)
The quickstart walks through this. The documentation covers the template tag and its options, every setting, thumbnails on Amazon S3 and troubleshooting.
- Resize to a box, a width or a height. Crop by position, percentage, pixels or a crop box, crop to the busiest part of the image, or cut plain borders first.
- JPEG, PNG, GIF, WEBP and AVIF output, with quality, progressive JPEG, grayscale, padding, rounded corners and blur. Animated GIFs stay animated with Pillow and libvips.
- Follows the EXIF orientation of photos.
- Any Django storage for sources and thumbnails, Amazon S3 included. The key-value store, your database read through your cache or Redis, remembers every thumbnail, so a cached one costs no storage request.
- An
ImageFieldthat validates uploads, an admin widget with a preview, and placeholder images for developing without the real media. - Alternative resolutions for high-density screens, and the
is_portraitandmarginfilters for layout. - Django 5.2, 6.0 and 6.1, following the Django supported versions policy, on Python 3.10 and later.
The engine does the resizing. Set it with THUMBNAIL_ENGINE; Pillow is the
default.
- Pillow, the default:
pip install "sorl-thumbnail[pil]". - libvips through pyvips:
pip install "sorl-thumbnail[vips]". - ImageMagick, through its
convertandidentifycommands. Also reads PDF pages. - GraphicsMagick, the same engine through
gm convertandgm identify. - Wand, a Python binding for ImageMagick:
pip install "sorl-thumbnail[wand]". - pgmagick, a Python binding for GraphicsMagick:
pip install "sorl-thumbnail[pgmagick]".
Each engine has an example gallery on the website, and the documentation lists which options each one supports.
Other libraries also register a thumbnail template library. Load
sorl-thumbnail's tags as sorl_thumbnail instead, the tag is the same:
{% load sorl_thumbnail %}
Ask in the Q&A category of GitHub Discussions. Report bugs in the issue tracker.
Pull requests are welcome. The contributing guide explains how to run the tests and send a change. Using AI tools is fine if you say so and test the change yourself; pull requests sent by scripts are closed. By contributing you agree to the Code of Conduct. To report a security issue, follow the security policy instead of opening a public issue.
The tests run with tox through uv, one environment per Python, Django and engine:
uvx --with tox-uv tox -l uvx --with tox-uv tox -e py312-django52-pil
The Pillow and libvips environments need nothing else. The others need the engine's tools, see the requirements, or run them in Docker as the contributing guide shows.
BSD 3-Clause, see the LICENSE file.