Skip to content

Instantly share code, notes, and snippets.

@archatas
Last active July 23, 2025 12:11
Show Gist options
  • Save archatas/abcb5c5bc33a1301fe3aeec371a65b10 to your computer and use it in GitHub Desktop.
Save archatas/abcb5c5bc33a1301fe3aeec371a65b10 to your computer and use it in GitHub Desktop.
Generate django-imagekit versions on the fly
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,
}
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