website/hub/services/admin/images.py

130 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.contrib import admin
from django.utils.html import format_html
from django.urls import reverse
from django.utils.safestring import mark_safe
from ..models.images import ImageLibrary
@admin.register(ImageLibrary)
class ImageLibraryAdmin(admin.ModelAdmin):
"""
Admin interface for the Image Library.
"""
list_display = [
"image_thumbnail",
"name",
"category",
"get_dimensions",
"get_file_size_display",
"usage_count",
"uploaded_by",
"uploaded_at",
]
list_filter = [
"category",
"uploaded_at",
"uploaded_by",
]
search_fields = [
"name",
"description",
"alt_text",
"tags",
]
readonly_fields = [
"width",
"height",
"file_size",
"usage_count",
"uploaded_at",
"updated_at",
"image_preview",
]
prepopulated_fields = {"slug": ("name",)}
fieldsets = (
("Image Information", {"fields": ("name", "slug", "description", "alt_text")}),
("Image File", {"fields": ("image", "image_preview")}),
("Categorization", {"fields": ("category", "tags")}),
(
"Metadata",
{
"fields": ("width", "height", "file_size", "usage_count"),
"classes": ("collapse",),
},
),
(
"Timestamps",
{
"fields": ("uploaded_by", "uploaded_at", "updated_at"),
"classes": ("collapse",),
},
),
)
def image_thumbnail(self, obj):
"""
Display small thumbnail in list view.
"""
if obj.image:
# Use img tag for all images in list view to maintain clickability
# SVG files will still display correctly with img tag
return format_html(
'<img src="{}" width="50" height="50" style="object-fit: cover; border-radius: 4px;" />',
obj.image.url,
)
return "No Image"
image_thumbnail.short_description = "Thumbnail"
def image_preview(self, obj):
"""
Display larger preview in detail view.
"""
if obj.image:
if obj.is_svg():
# For SVG files in detail view, use object tag for better rendering
# This is only for display, not for clickable elements
return format_html(
'<div style="pointer-events: none;">'
'<object data="{}" type="image/svg+xml" style="max-width: 300px; max-height: 300px; border-radius: 4px; background: #f5f5f5;">'
'<img src="{}" style="max-width: 300px; max-height: 300px; border-radius: 4px;" />'
"</object>"
"</div>",
obj.image.url,
obj.image.url,
)
else:
return format_html(
'<img src="{}" style="max-width: 300px; max-height: 300px; border-radius: 4px;" />',
obj.image.url,
)
return "No Image"
image_preview.short_description = "Preview"
def get_dimensions(self, obj):
"""
Display image dimensions.
"""
if obj.width and obj.height:
return f"{obj.width} × {obj.height}"
return "Unknown"
get_dimensions.short_description = "Dimensions"
def save_model(self, request, obj, form, change):
"""
Set uploaded_by field to current user if not already set.
"""
if not change: # Only set on creation
obj.uploaded_by = request.user
super().save_model(request, obj, form, change)
class Media:
css = {"all": ("admin/css/image_library.css",)}