from django import forms
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.urls import reverse
from ..models.images import ImageLibrary
class ImageLibraryWidget(forms.Select):
"""
Custom widget for selecting images from the library with thumbnails.
"""
def __init__(self, attrs=None, choices=(), show_thumbnails=True):
self.show_thumbnails = show_thumbnails
super().__init__(attrs, choices)
def format_value(self, value):
"""
Format the selected value for display.
"""
if value is None:
return ""
return str(value)
def render(self, name, value, attrs=None, renderer=None):
"""
Render the widget with thumbnails.
"""
if attrs is None:
attrs = {}
# Add CSS class for styling
attrs["class"] = attrs.get("class", "") + " image-library-select"
# Get all images for the select options
images = ImageLibrary.objects.all().order_by("name")
# Build choices with thumbnails
choices = [("", "--- Select an image ---")]
for image in images:
thumbnail_html = ""
if self.show_thumbnails and image.image:
# Use img tag for all images in dropdowns to maintain functionality
# SVG files will still display correctly with img tag
thumbnail_html = format_html(
' ',
image.image.url,
)
choice_text = (
f"{image.name} ({image.get_category_display()}){thumbnail_html}"
)
choices.append((image.pk, choice_text))
# Build the select element
select_html = format_html(
'',
name,
attrs.get("id", ""),
self._build_attrs_string(attrs),
self._build_options(choices, value),
)
# Add preview area
preview_html = ""
if value:
try:
image = ImageLibrary.objects.get(pk=value)
# Use img tag for all images in preview for consistency
# Add SVG indicator in the text if it's an SVG file
svg_indicator = " (SVG)" if image.is_svg() else ""
preview_html = format_html(
'
{} - {}x{} - {}{}
' "