Sorl Thumbnail
Sorl Thumbnail is a popular and flexible Django application for generating image thumbnails. It handles image resizing, cropping, and caching, offering support for various storage backends (local, S3, Google Cloud Storage) and image processing engines (Pillow, ImageMagick). The current version is 13.0.0, with an active release cadence, typically aligning with Django and Python version updates.
Warnings
- breaking In version 13.0.0, `THUMBNAIL_STORAGE` should now be an alias referring to an entry in Django's `STORAGES` setting, instead of a direct dotted path to a storage class. While the old way is still supported, using aliases is crucial for correct serialization and preserving storage options (like S3 bucket names) when thumbnails are cached and retrieved, especially with cloud backends. Upgrading may orphan existing thumbnail references if not properly handled during migration.
- deprecated The `THUMBNAIL_KVSTORE` setting is deprecated since version 12.11.0. In future versions, only the Django cache-based store will be used. If you rely on custom KV stores (like DBM or a direct Redis KVStore setup), you should transition to using Django's cache framework.
- gotcha Sorl Thumbnail relies on a Key-Value Store for its operation. The default is a cached database, which requires `python manage.py migrate` to create necessary tables. For better performance, especially in production, a fast cache like Memcached or Redis is highly recommended. Not running migrations or having a slow/unconfigured KV store can lead to performance issues or errors.
- gotcha Generating many thumbnails for the first time on a page can be slow, potentially causing request timeouts on web servers if the timeout is set too low. This is due to the synchronous nature of thumbnail generation on first access.
- breaking Sorl Thumbnail has dropped support for older Python and Django versions incrementally. For instance, Python 3.7 support was removed in 12.10.0, Python 3.8/3.9 in 13.0.0, and Django 3.2, 4.0, 4.1 in 12.11.0. Running with unsupported versions can lead to unexpected errors or vulnerabilities.
Install
-
pip install sorl-thumbnail Pillow -
pip install sorl-thumbnail Pillow redis django-storages
Imports
- ImageField
from sorl.thumbnail import ImageField
- get_thumbnail
from sorl.thumbnail import get_thumbnail
- {% load thumbnail %}
{% load thumbnail %}
Quickstart
import os
import django
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import models
settings.configure(
INSTALLED_APPS=[
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'sorl.thumbnail',
'myapp'
],
DATABASES={
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
},
MEDIA_ROOT=os.path.join(os.path.dirname(__file__), 'media'),
STATIC_ROOT=os.path.join(os.path.dirname(__file__), 'static'),
STATIC_URL='/static/',
THUMBNAIL_KEY_PREFIX='sorl-test-',
THUMBNAIL_STORAGE='default',
STORAGES = {
'default': {
'BACKEND': 'django.core.files.storage.FileSystemStorage'
},
'thumbnails': {
'BACKEND': 'django.core.files.storage.FileSystemStorage'
}
},
SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-testing'),
TEMPLATES=[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
],
)
django.setup()
class Item(models.Model):
image = ImageField(upload_to='items')
def __str__(self):
return f"Item {self.pk}"
# --- Example Usage ---
from sorl.thumbnail import get_thumbnail
from django.template import Context, Template
# Create a dummy image file
dummy_image = SimpleUploadedFile("test_image.jpg", b"file_content", content_type="image/jpeg")
# Save an item with the image
item = Item.objects.create(image=dummy_image)
# Generate a thumbnail using the low-level API
thumbnail_obj = get_thumbnail(item.image, '100x100', crop='center', quality=95)
print(f"Generated thumbnail URL: {thumbnail_obj.url}")
# Simulate template rendering (requires a request context usually)
# For a true runnable example without a full Django app, this is tricky.
# This part demonstrates the template tag usage conceptually.
# In a real Django project, you'd put {% load thumbnail %} and the tag in your .html file.
# Example template snippet
template_str = """
{% load thumbnail %}
<img src="{% thumbnail item.image '50x50' crop='center' as im %}{{ im.url }}{% endthumbnail %}">
"""
template = Template(template_str)
context = Context({'item': item})
# This will likely fail without a full Django test setup that handles file storage properly
# print(template.render(context))
# Clean up (optional, for real apps, let Django manage)
item.image.delete(save=False)
item.delete()