130 lines
3.8 KiB
Python
130 lines
3.8 KiB
Python
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",)}
|