{"id":6243,"library":"sorl-thumbnail","title":"Sorl Thumbnail","description":"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.","status":"active","version":"13.0.0","language":"en","source_language":"en","source_url":"https://github.com/jazzband/sorl-thumbnail","tags":["django","image-processing","thumbnails","media","caching","jazzband"],"install":[{"cmd":"pip install sorl-thumbnail Pillow","lang":"bash","label":"Basic Installation"},{"cmd":"pip install sorl-thumbnail Pillow redis django-storages","lang":"bash","label":"Installation with Redis and Cloud Storages"}],"dependencies":[{"reason":"Core framework integration.","package":"Django"},{"reason":"Required for image processing and manipulation. Other engines like ImageMagick/GraphicsMagick (with `wand` or `pgmagick`) are also supported but Pillow is the most common.","package":"Pillow","optional":false},{"reason":"Optional, but highly recommended for a faster Key-Value Store backend than the default cached database.","package":"redis","optional":true},{"reason":"Optional, required for integrating with cloud storage services like Amazon S3 or Google Cloud Storage.","package":"django-storages","optional":true}],"imports":[{"symbol":"ImageField","correct":"from sorl.thumbnail import ImageField"},{"symbol":"get_thumbnail","correct":"from sorl.thumbnail import get_thumbnail"},{"note":"The template tag library is 'thumbnail', not 'sorl.thumbnail'. If clashing with another 'thumbnail' tag, use `{% load sorl_thumbnail %}` (introduced in v12.0) or Django's `libraries` option to alias it.","wrong":"{% load sorl.thumbnail %}","symbol":"{% load thumbnail %}","correct":"{% load thumbnail %}"}],"quickstart":{"code":"import os\nimport django\nfrom django.conf import settings\nfrom django.core.files.uploadedfile import SimpleUploadedFile\nfrom django.db import models\n\nsettings.configure(\n    INSTALLED_APPS=[\n        'django.contrib.auth',\n        'django.contrib.contenttypes',\n        'django.contrib.sessions',\n        'django.contrib.messages',\n        'django.contrib.staticfiles',\n        'sorl.thumbnail',\n        'myapp'\n    ],\n    DATABASES={\n        'default': {\n            'ENGINE': 'django.db.backends.sqlite3',\n            'NAME': ':memory:',\n        }\n    },\n    MEDIA_ROOT=os.path.join(os.path.dirname(__file__), 'media'),\n    STATIC_ROOT=os.path.join(os.path.dirname(__file__), 'static'),\n    STATIC_URL='/static/',\n    THUMBNAIL_KEY_PREFIX='sorl-test-',\n    THUMBNAIL_STORAGE='default',\n    STORAGES = {\n        'default': {\n            'BACKEND': 'django.core.files.storage.FileSystemStorage'\n        },\n        'thumbnails': {\n            'BACKEND': 'django.core.files.storage.FileSystemStorage'\n        }\n    },\n    SECRET_KEY=os.environ.get('DJANGO_SECRET_KEY', 'a-very-secret-key-for-testing'),\n    TEMPLATES=[\n        {\n            'BACKEND': 'django.template.backends.django.DjangoTemplates',\n            'APP_DIRS': True,\n            'OPTIONS': {\n                'context_processors': [\n                    'django.template.context_processors.debug',\n                    'django.template.context_processors.request',\n                    'django.contrib.auth.context_processors.auth',\n                    'django.contrib.messages.context_processors.messages',\n                ],\n            },\n        },\n    ],\n)\ndjango.setup()\n\nclass Item(models.Model):\n    image = ImageField(upload_to='items')\n\n    def __str__(self):\n        return f\"Item {self.pk}\"\n\n# --- Example Usage ---\nfrom sorl.thumbnail import get_thumbnail\nfrom django.template import Context, Template\n\n# Create a dummy image file\ndummy_image = SimpleUploadedFile(\"test_image.jpg\", b\"file_content\", content_type=\"image/jpeg\")\n\n# Save an item with the image\nitem = Item.objects.create(image=dummy_image)\n\n# Generate a thumbnail using the low-level API\nthumbnail_obj = get_thumbnail(item.image, '100x100', crop='center', quality=95)\nprint(f\"Generated thumbnail URL: {thumbnail_obj.url}\")\n\n# Simulate template rendering (requires a request context usually)\n# For a true runnable example without a full Django app, this is tricky.\n# This part demonstrates the template tag usage conceptually.\n# In a real Django project, you'd put {% load thumbnail %} and the tag in your .html file.\n\n# Example template snippet\ntemplate_str = \"\"\"\n{% load thumbnail %}\n<img src=\"{% thumbnail item.image '50x50' crop='center' as im %}{{ im.url }}{% endthumbnail %}\">\n\"\"\"\n\ntemplate = Template(template_str)\ncontext = Context({'item': item})\n\n# This will likely fail without a full Django test setup that handles file storage properly\n# print(template.render(context))\n\n# Clean up (optional, for real apps, let Django manage)\nitem.image.delete(save=False)\nitem.delete()\n","lang":"python","description":"To get started, install `sorl-thumbnail` and `Pillow`, then add `sorl.thumbnail` to your Django `INSTALLED_APPS`. If using the cached database key-value store (the default), run `python manage.py migrate`. You can then use the `ImageField` in your models or the `{% thumbnail %}` template tag to generate and display thumbnails. Remember to configure `MEDIA_ROOT` and potentially `STORAGES` in your Django settings. This quickstart includes a basic Django setup for a runnable example."},"warnings":[{"fix":"Update your Django `settings.py`. Define your storage backend in `STORAGES` and set `THUMBNAIL_STORAGE` to its alias. Example:\n```python\nSTORAGES = {\n    \"default\": {\n        \"BACKEND\": \"django.core.files.storage.FileSystemStorage\",\n    },\n    \"thumbnails\": {\n        \"BACKEND\": \"storages.backends.s3boto3.S3Boto3Storage\",\n        \"OPTIONS\": {\n            \"bucket_name\": \"my-thumbnail-bucket\",\n        },\n    },\n}\nTHUMBNAIL_STORAGE = 'thumbnails'\n```","message":"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.","severity":"breaking","affected_versions":">=13.0.0"},{"fix":"Ensure your Django `CACHES` setting is configured correctly and that `sorl-thumbnail` is using the default cached database KV store. If you were using a Redis KVStore, configure Redis as a Django cache backend instead. Example `settings.py`:\n```python\nCACHES = {\n    'default': {\n        'BACKEND': 'django_redis.cache.RedisCache',\n        'LOCATION': os.environ.get('REDIS_URL', 'redis://127.0.0.1:6379/1'),\n    }\n}\n# THUMBNAIL_KVSTORE will implicitly use 'default' cache\n```","message":"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.","severity":"deprecated","affected_versions":">=12.11.0"},{"fix":"After adding `sorl.thumbnail` to `INSTALLED_APPS`, always run `python manage.py migrate`. For production, configure a robust cache in your `settings.py` (e.g., Redis via `django-redis`) and ensure it's properly set up. Install `redis` package for Redis integration.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Increase your web server's request timeout (e.g., Gunicorn's `--timeout` setting). For frequently accessed images, consider pre-generating thumbnails using management commands (`thumbnail cleanup --all`) or an asynchronous task queue (like Celery) to avoid on-demand generation during user requests.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always check the `sorl-thumbnail` release notes for compatibility with your Python and Django versions before upgrading or starting a new project. Ensure your environment meets the `requires_python` and Django compatibility of the `sorl-thumbnail` version you are using. For v13.0.0, Python >= 3.10 is required.","message":"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.","severity":"breaking","affected_versions":"<13.0.0 for newer Python/Django, check specific release notes for details."}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}