Last active
July 23, 2025 12:11
-
-
Save archatas/abcb5c5bc33a1301fe3aeec371a65b10 to your computer and use it in GitHub Desktop.
Generate django-imagekit versions on the fly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from imagekit import ImageSpec | |
| from imagekit.processors import ResizeToFill, ResizeToFit | |
| from PIL import Image | |
| class Avatar80x80(ImageSpec): | |
| processors = [ResizeToFill(80, 80)] | |
| format = "PNG" | |
| VERSIONS = { | |
| "core:avatar80x80": Avatar80x80, | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import json | |
| import base64 | |
| import hashlib | |
| from django import forms | |
| from django.http import HttpResponse | |
| from django.shortcuts import redirect | |
| from django.core.cache import cache | |
| from django.core.files.storage import default_storage | |
| from django.utils.translation import gettext | |
| from .generators import VERSIONS | |
| VERSION_CHOICES = [(key, key) for key in VERSIONS.keys()] | |
| PIXEL_GIF_DATA = base64.b64decode( | |
| "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" | |
| ) | |
| class ImageVersionForm(forms.Form): | |
| image_path = forms.CharField(required=True) | |
| version = forms.ChoiceField(required=True, choices=VERSION_CHOICES) | |
| def clean_image_path(self): | |
| image_path = self.cleaned_data["image_path"] | |
| if image_path.startswith("http") or ".." in image_path: | |
| raise forms.ValidationError(gettext("Invalid image path")) | |
| if not default_storage.exists(image_path): | |
| raise forms.ValidationError(gettext("Image does not exist")) | |
| if default_storage.size(image_path) > settings.MAX_IMAGE_FILE_SIZE["bytes"]: | |
| raise forms.ValidationError( | |
| gettext("Original image is too big. It should be less than {file_size}.").format(file_size=settings.MAX_IMAGE_FILE_SIZE["humanized_size"]) | |
| ) | |
| return image_path | |
| def get_generator_class(self): | |
| return VERSIONS[self.cleaned_data["version"]] | |
| def generate(self): | |
| from django.core.files import File | |
| from imagekit.cachefiles import ImageCacheFile | |
| image_path = self.cleaned_data["image_path"] | |
| VersionGenerator = self.get_generator_class() | |
| with default_storage.open(image_path) as source_file: | |
| image_generator = VersionGenerator(source=File(source_file, name=image_path)) | |
| cached = ImageCacheFile(image_generator) | |
| cached.generate(force=False) | |
| cached_url = cached.url | |
| return cached_url | |
| def show_image_version(request): | |
| form = ImageVersionForm(data=request.GET) | |
| if form.is_valid(): | |
| # Create cache key from form data | |
| cache_key = hashlib.md5(str(sorted(request.GET.items())).encode()).hexdigest() | |
| cache_key = f"image_url_{cache_key}" | |
| # Try to get URL from cache | |
| if not (result_url := cache.get(cache_key)): | |
| result_url = form.generate() | |
| cache.set(cache_key, result_url, 60 * 60 * 24) # 24 hours | |
| return redirect(result_url) | |
| # Error fallback | |
| json_data = json.dumps(form.errors) | |
| response = HttpResponse(PIXEL_GIF_DATA, content_type="image/gif") | |
| response["Hints"] = json_data | |
| return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment