This release is a pre-release and may not be stable for production use.
Easy Thumbnails
A powerful, yet easy to implement thumbnailing application for Django 4.2+
Below is a quick summary of usage. For more comprehensive information, view the
full documentation online or the peruse the project's docs directory.
Installation
Run pip install fdemmer-easy-thumbnails.
Thumbnailing SVG images is supported when installed with the [svg] extra
(pip install fdemmer-easy-thumbnails[svg]). See the SVG support page in
the full documentation for details.
Add easy_thumbnails to your INSTALLED_APPS setting:
INSTALLED_APPS = (
...
'easy_thumbnails',
)
Run manage.py migrate easy_thumbnails.
Example usage
Thumbnail options can be predefined in settings.THUMBNAIL_ALIASES or just
specified in the template or Python code when run.
Using a predefined alias
Given the following setting:
THUMBNAIL_ALIASES = {
'': {
'avatar': {'size': (50, 50), 'crop': True},
},
}
Template:
{% load thumbnail %}
<img src="{{ profile.photo|thumbnail_url:'avatar' }}" alt="" />
Python:
from easy_thumbnails.files import get_thumbnailer
thumb_url = get_thumbnailer(profile.photo)['avatar'].url
Manually specifying size / options
Template:
{% load thumbnail %}
<img src="{% thumbnail profile.photo 50x50 crop %}" alt="" />
Python:
from easy_thumbnails.files import get_thumbnailer
options = {'size': (100, 100), 'crop': True}
thumb_url = get_thumbnailer(profile.photo).get_thumbnail(options).url
Using in combination with other thumbnailers
Alternatively, you load the templatetags by {% load easy_thumbnails_tags %}
instead of traditional {% load thumbnail %}. It's especially useful in
projects that do make use of multiple thumbnailer libraries that use the
same name (thumbnail) for the templatetag module:
{% load easy_thumbnails_tags %}
<img src="{% thumbnail profile.photo 50x50 crop %}" alt="" />
Fields
You can use ThumbnailerImageField (or ThumbnailerField) for easier
access to retrieve or generate thumbnail images.
For example:
from easy_thumbnails.fields import ThumbnailerImageField
class Profile(models.Model):
user = models.OneToOneField('auth.User')
photo = ThumbnailerImageField(upload_to='photos', blank=True)
Accessing the field's predefined alias in a template:
{% load thumbnail %}
<img src="{{ profile.photo.avatar.url }}" alt="" />
Accessing the field's predefined alias in Python code:
thumb_url = profile.photo['avatar'].url
Thumbnail options
crop
Before scaling the image down to fit within the size bounds, it first cuts
the edges of the image to match the requested aspect ratio.
Use crop="smart" to try to keep the most interesting part of the image,
Use crop="0,10" to crop from the left edge and a 10% offset from the
top edge. Crop from a single edge by leaving dimension empty (e.g.
crop=",0"). Offset from the right / bottom by using negative numbers
(e.g., crop="-0,-10").
Often used with the upscale option, which will allow enlarging of the image
during scaling.
quality=XX
Changes the quality of the output JPEG thumbnail. Defaults to 85.
In Python code, this is given as a separate option to the get_thumbnail
method rather than just alter the other.
keep_icc_profile
If True, when saving a thumbnail with the alias that defines this option, the
ICC profile of the image will be preserved in the thumbnail, if present in the first place.
Other options
Valid thumbnail options are determined by the "thumbnail processors" installed.
See the reference documentation for a complete list of options provided by the default thumbnail processors.
Changelog
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning (up to 2.x, version numbers were not strictly semantic).
[3.4.0rc1] - 2026-10-14
- Add
Source.thumb_hash, filled when the first thumbnail of a source is generated by the function set in the newTHUMBNAIL_HASHERsetting. The default,easy_thumbnails.hashers.default, generates a ThumbHash and requires the newthumbhashextra (fast-thumbhash-rs). Includes a migration. - Add
Thumbnailer.prefetch_thumbnailsandThumbnailer.prefetch_aliasesto fetch theThumbnailrecords of several thumbnails together with theirThumbnailDimensionsandSourcein a single query. Followingget_thumbnailcalls for these thumbnails need no further queries, and withTHUMBNAIL_CACHE_DIMENSIONSalso local storage gets the dimensions from the database. - With remote thumbnail storage,
get_existing_thumbnailfetches the records of the regular and the transparent thumbnail name (and theSource) with a single query instead of one query each, and keeps them for repeated lookups. - Add
alias_or_sizenamer, which names thumbnails after their alias or, if there is none, their size (e.g.source.medium_large.jpgorsource.800x600.jpg). - The
formatoption is no longer included inprepared_optionspassed to namers, since it already determines the thumbnail file extension. Thumbnail names no longer contain aformat-<ext>part. - Add tests and a docstring for
ThumbnailOptions.prepared_options, and document how to write custom namers.
[3.3.0] - 2026-10-06
- Add
formatthumbnail option (jpeg,webporavif) to set the output format per thumbnail. - Add
thumbnail purgemanagement command to delete thumbnails (files and database records) while keepingSourcerecords, optionally filtered by--include/--excludeand--alias.
[3.2.0] - 2026-08-02 [YANKED]
- This release was yanked and replaced by 3.3.0.
[3.1.3] - 2026-10-06
- Fix no-op
excludefilter for empty/nullFileFieldvalues in thethumbnailmanagement command. - Fix thumbnail names removing the storage location from anywhere in the source path instead of only from its start.
- Fix
get_storage_hash()hashingbuiltins.objectfor lazy storages that were not yet set up (e.g.default_storage), producing a wrong hash. - The source distribution now includes the
demoproject(not the wheel).
[3.1.2] - 2026-10-03
thumbnail storagesoutput is now column-aligned and includes the storage class name.- Refactor
thumbnail cleanup: Source deletion is batched viaitertools.batched(backported for Python < 3.12), messages are reworded, and-v2logs each storage existence check. - Remove unused
dimensionsargument fromdatabase_get_image_dimensions(). - Fix
thumbnail storagescommand to show all storages, even when multiple aliases share the same storage hash. - Fix
ThumbnailerFieldFile.delete_thumbnails()ignoring thesource_cacheargument.
[3.1.1] - 2026-07-26
- Update documentation links to the new GitHub Pages site.
- Drop the unused Read the Docs config.
[3.1.0] - 2026-07-26
- Add
thumbnail storagessubcommand: lists each configured storage's alias and storage hash. - Add
thumbnail cleanup --delete-with-missing-storageoption: deletesSourcerecords whose storage hash no longer matches any alias configured in Django'sSTORAGESsetting. - Add
thumbnail source_filessubcommand: lists file paths stored in everyThumbnailerImageFieldacross installed apps, with--summary,--include, and--excludeoptions for filtering by app/model/field. - Add
thumbnail source_cleanupsubcommand: deletes orphanedSourcerecords whose(storage_hash, name)no longer matches anyThumbnailerImageFieldvalue. - Rename the
thumbnail_cleanupmanagement command to acleanupsubcommand of a new, unifiedthumbnailmanagement command. Update anypython manage.py thumbnail_cleanupinvocations topython manage.py thumbnail cleanup. - Fix SVG thumbnails rendering at 0.75x the requested size when
svglib>= 2.0 is installed:VIL.Imagenow writes explicitptunits on SVGwidth/heightattributes instead of unitless values, whose interpretation changed between svglib versions.
[3.0.1] - 2026-05-04
- Refactor
ThumbnailCollectionCleaner.clean_upto reduce McCabe complexity by extracting_build_query,_process_source, and_delete_thumbnail. - Fix
thumbnail_cleanup: storage errors during source existence check no longer cause false-positive deletion of thumbnails.
[3.0.0] - 2026-04-16
- Fork published as
fdemmer-easy-thumbnailson PyPI. - Add support for Django 5.2 and 6.0, Python 3.13 and 3.14.
- Add
thumbnail_cleanupmanagement command documentation. - Major modernization: migrated to
src/layout,pyproject.toml-only build configuration, pytest, uv/tox, and pathlib. - Drop support for Python < 3.9 and Django < 4.2.
[2.10.2] - 2025-02-11
- Remove experimental support for animated image formats due to problems with MPO (Multi-Picture Format) images.
[2.10.1] - 2025-01-25
- Fix for non-filesystem storage (regression in 26e8f9f of 2.8.5).
[2.10] - 2024-09-11
- Add support for Django 5.1.
- Experimental support for animated image formats. See documentation for more infos.
- Drop support for Python 3.8.
- Drop support for Django 4.1 and earlier.
- Fix #642: Do not scale images (SVG) without size information.
- Fix #366: Keep ICC profile when saving image, if present.
[2.9] - 2024-07-25
- Add support for Django 4.2 storages (mandatory in Django 5.1).
[2.8.5] - 2023-01-09
- Fix regression introduced in version 2.8.4. Argument
qualityis not removed for images of type.webp.
[2.8.4] - 2022-12-19
- Replace deprecated Pillow constants with newer counterparts. Check https://pillow.readthedocs.io/en/stable/releasenotes/9.1.0.html#deprecations for details.
- Fix problem when thumbnailing images of type TIFF. PIL's
TiffImagePlugindoesn't like argumentquality.
[2.8.3] - 2022-08-02
- Fix regression in library detection introduced in version 2.8.2.
[2.8.2] - 2022-07-31
- Installation of easy-thumbnails now optionally depends on the reportlab library.
[2.8.1] - 2022-01-20
- Add support for Django 4.
- New
THUMBNAIL_IMAGE_SAVE_OPTIONSsetting. - Fix #587: Uploading SVG Images to S3 storage.
[2.8.0] - 2021-11-03
- Add support for thumbnailing SVG images. This is done by adding an emulation layer named VIL, which aims to be compatible with PIL. All thumbnailing operations, such as scaling and cropping behave like pixel images.
- Remove configuration directives
THUMBNAIL_HIGH_RESOLUTIONandTHUMBNAIL_HIGHRES_INFIXfrom easy-thumbnails setting directives.
[2.7.2] - 2021-10-17
- Add support for Django 3.2 and Python 3.10.
- In management command
thumbnail_cleanup, replaceprintstatements withstdout.write. - Use Python format strings wherever possible.
- Fix #563: Do not close image after loading content.
[2.7.1] - 2020-11-23
- Add support for Django 3.1.
[2.7.0] - 2019-12-15
- Add support for Django 3.0.
- Drop support for Python 2.
- Drop support for Django < 1.11.
- Drop support for Django 2.0, 2.1.
[2.6.0] - 2019-02-03
- Add testing for Django 2.2 (no code changes required).
[2.5.0] - 2017-10-31
- Support Django versions up to 1.11. Version 2.0 is in beta.
- Remove all references to South migrations.
- Fix pickle/unpickle machinery. The ThumbnailerField fields no longer generated thumbnails.
[2.4.2] - 2017-09-14
- Supported Django versions are now 1.8 or 1.10+, Python 2.7 minimum.
- Fix IOError saving JPEG files with transparency on Pillow 4.2+.
- Fix #450, #473: fixed int/string is not a callable in management command.
- Fix #456: Delete method of ThumbnailerFieldFile is called twice.
[2.4.1] - 2017-04-05
- Add
easy_thumbnails_tagstemplate tag mirror to allow multiple thumbnailer libraries to coexist happily. - New minimum requirement of Django 1.4 or 1.7+.
- Upgrades to avoid deprecation warnings.
- Django 1.8+ compatibility for
thumbnail_cleanupcommand. - Limit pillow to its final compatible version when on Python 2.6.
- Fix EXIF orientation to use transpose.
- Fix app settings not working in Django 1.11.
- Fix a bad conditional check causing incorrect behaviour in autocropping transparent images.
- Fix tests.
[2.3] - 2015-12-11
- New
Aliasnamer. - Allow
HIGH_RESOLUTIONargument on thumbnail template tag. - Add a
data_urifilter to allow rendering of an image inline as a data uri. - Avoid a potential concurrency issue with creating the cache.
- Remove some vestigial processor arguments.
- Fix incorrect use of select_related for source thumbnail model.
- Add logic to correctly handle thumbnail images on deferred models (e.g. when
using
.only()).
[2.2.1] - 2014-12-30
- Option
zoomcan also be used by itself, without combining it withcrop.
[2.2] - 2014-10-04
- Fix migrations for Django 1.7 final.
- Fix contain bad image EXIFs being able to still raise an exception.
[2.1] - 2014-08-13
- JPEG files can now be saved with progressive encoding. By default, any image
with a dimension larger than 100px will be saved progressively. Configured
with the
THUMBNAILER_PROGRESSIVEsetting. - Fix Python 3.4 installation issue.
- Avoid an OverflowError due to invalid EXIF data.
- Fix bug causing JPEG images to be saved without optimization.
[2.0.1] - 2014-04-26
- Fix packaging issue with old south migrations.
[2.0] - 2014-04-25
- Add
targetoption to the scale_and_crop processor, allowing for image focal points when cropping (or zooming) an image. - Add a THUMBNAIL_NAMER option which takes a function used to customize the thumbnail filename.
- New
subsamplingoption to reduce color subsampling of JPEG images, providing sharper color borders for a small increase in file size. - Use Django 1.7 migrations. Thanks Trey Hunner. Note: if using South, read the installation docs for required settings changes.
- Make ThumbnailerImageField.resize_source reflect change in extension.
- Reimplementation of the
thumbnail_cleanupcommand. Thanks Jørgen Abrahamsen. - More efficient thumbnail default storage. Thanks Sandip Agarwal.
[1.5] - 2014-03-05
- Optional postprocessor for image optimization. Thanks Jacob Rief!
- Thumbnail dimensions can now optionally be cached. Thanks David Novakovic.
- New
zoomoption to generate a thumbnail of a source image with a percentage clipped off each side. - New
backgroundsource processor that can add a border color to ensure scaled images fit within the exact dimensions given. - Added configuration option to specify the infix used for high resolution image handling.
- Better support for multiple source generators.
- Update method used to check for modification dates of source and thumbnail images. Thanks Ben Roberts.
- Better thumbnail_high_resolution handling, including the ability to switch on
and off explicitly with a
HIGH_RESOLUTIONthumbnail option. - More remote storages optimization.
[1.4] - 2013-09-23
- Allow the
{% thumbnail %}tag to also accept aliases. Thanks Simon Meers! - Considerable speed up for remote storages by reducing queries. Brent O'Connor spent a lot of time debugging this, so thank you epicserve!
- Make
replace_alphaactually work correctly. - Fix exception being raised when image exists in cache but doesn't actually exist in the storage.
- Fix Python 2.5 compatibility.
[1.3] - 2013-06-17
- Add the ability to generate retina quality thumbnails in addition to the standard ones (off by default).
- Some more Django 1.5 fixes.
- Fix an issue with
Thumbnail.urlnot working correctly.
[1.2] - 2013-01-23
- Django 1.5 compatibility.
- Fix a problem with the
ImageClearableFileInputwidget.
[1.1] - 2012-08-29
- Add a way to avoid generating thumbnails if they don't exist already (with a signal to deal with them elsewhere).
- Add a
thumbnailer_passivefilter to allow templates to use the non-generating thumbnails functionality when dealing with aliases.
[1.0.3] - 2012-05-30
- Change the exception to catch from 1.0.2 to IOError.
[1.0.2] - 2012-05-29
- Catch an OSError exception when trying to get the EXIF data of a touchy image.
[1.0.1] - 2012-05-23
- Introduce a
thumbnail_createdsignal. - Fix a Django 1.2 backwards incompatibility in
easy_thumbnails.conf.
[1.0] - 2012-05-07
- Introduction of aliased thumbnails.
- Start of sane versioning numbers.
Metadata
Release files for fdemmer-easy-thumbnails 3.4rc1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| fdemmer_easy_thumbnails-3.4rc1.tar.gz | 108.4 kB | Without provenance | Details for fdemmer_easy_thumbnails-3.4rc1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| fdemmer_easy_thumbnails-3.4rc1-py3-none-any.whl | Python 3 | none | any | Details for fdemmer_easy_thumbnails-3.4rc1-py3-none-any.whl |
Total release size: 171.4 kB
Release files / fdemmer_easy_thumbnails-3.4rc1.tar.gz
| Download URL | fdemmer_easy_thumbnails-3.4rc1.tar.gz |
|---|---|
| Size | 108.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bee87be1edf98f86ade2ee7c406dcd8aa2e244fd992edbc35e83573f99d013c4
|
|
BLAKE2b-256 checksum How to use checksums |
30cfc03933cb7d0d1c33795f46a856474021f6cfc1c9069f334cbf7967f77d57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Release files / fdemmer_easy_thumbnails-3.4rc1-py3-none-any.whl
| Download URL | fdemmer_easy_thumbnails-3.4rc1-py3-none-any.whl |
|---|---|
| Size | 63.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
76f546e0011f9099ad9ab4a72debb6bd575e238cf86acccbf82c36ed7372e4ad
|
|
BLAKE2b-256 checksum How to use checksums |
c247ff2a91f10dd8799f02d3908e4ec61d338a8e07c2df493a29f7db57b323ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Security for fdemmer-easy-thumbnails 3.4rc1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.