muistox/gallery/admin.py

164 lines
6.1 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.http import JsonResponse
from django.shortcuts import get_object_or_404, render
from django.urls import path, reverse
from django.utils.html import format_html
from imagekit import ImageSpec
from imagekit.admin import AdminThumbnail
from imagekit.cachefiles import ImageCacheFile
from imagekit.processors import ResizeToFit
from gallery.models import Album, City, Location, Photo, Redir
# Thumbnail-luokka admin-näkymää varten
class AdminThumbnailSpec(ImageSpec):
processors = [ResizeToFit(100, 100)]
format = 'JPEG'
options = {'quality': 60}
def cached_admin_thumb(instance):
"""Palauttaa cachetetun thumbnailin, jos kuva on olemassa."""
if instance.photo:
cached = ImageCacheFile(AdminThumbnailSpec(instance.photo))
cached.generate()
return cached
return None
# 🔹 RedirAdmin uudelleenohjausten hallinta
class RedirAdmin(admin.ModelAdmin):
list_display = ('path', 'album', 'test_url')
search_fields = ('path',)
ordering = ('path',)
list_per_page = 30
list_editable = ('album',)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""Järjestää albumivalikon aakkosjärjestykseen."""
if db_field.name == "album":
kwargs["queryset"] = Album.objects.all().order_by('name')
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def test_url(self, obj):
"""Luo linkin, jolla voi testata uudelleenohjauksen."""
return format_html(
'<a href="/{}" target="_blank">http://nyymix.net/{}</a>',
obj.path, obj.path
)
test_url.short_description = "Test Redirection"
# 🔹 CityAdmin kaupunkien hallinta
class CityAdmin(admin.ModelAdmin):
list_display = ('name',)
search_fields = ('name',)
ordering = ('name',)
list_per_page = 30
# 🔹 LocationAdmin sijaintien hallinta
class LocationAdmin(admin.ModelAdmin):
list_display = ('city', 'place')
list_filter = ('city',)
ordering = ('city__name',)
search_fields = ('place', 'city__name',)
list_per_page = 30
# 🔹 AlbumAdmin albumien hallinta
class AlbumAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
list_display = ('name', 'location', 'album_date', 'is_public', 'upload_link', 'thumbnail')
search_fields = ('name',)
ordering = ('-album_date',)
list_per_page = 20
list_editable = ('is_public',)
readonly_fields = ['cover_preview']
change_form_template = "admin/gallery/album/change_form.html"
def get_urls(self):
"""Lisää mukautetun URL-reitin valokuvien lataamiselle."""
urls = super().get_urls()
custom_urls = [
path('<int:album_id>/upload/', self.admin_site.admin_view(self.upload_photos), name="gallery_album_upload"),
]
return custom_urls + urls
def upload_photos(self, request, album_id, *args, **kwargs):
"""Käsittelee valokuvien lataamisen albumiin."""
album = get_object_or_404(Album, id=album_id)
if request.method == 'POST' and request.FILES:
uploaded_files = request.FILES.getlist('photo')
if not uploaded_files:
return JsonResponse({"error": "No files uploaded."}, status=400)
Photo.objects.bulk_create([Photo(album=album, photo=file) for file in uploaded_files])
return JsonResponse({"message": "Photos uploaded successfully!"})
return render(request, 'admin/upload_photos.html', {'album': album})
def upload_link(self, obj):
"""Lisää 'Upload Photos' -painikkeen albumin muokkaussivulle."""
if obj.id:
url = reverse("admin:gallery_album_upload", kwargs={"album_id": obj.id})
return format_html('<a href="{}" class="button">Upload Photos</a>', url)
return "-"
upload_link.short_description = "Upload Photos"
def thumbnail(self, obj):
"""Näyttää albumin kansikuvan pikkukuvan."""
if obj.cover and obj.cover.photo:
return format_html(
'<img src="{}" style="width: 50px; height: auto;"/>',
obj.cover.photo_sm.url,
)
return "-"
thumbnail.short_description = "Thumbnail"
def cover_preview(self, obj):
"""Näyttää albumin kansikuvan suurempana esikatseluna."""
if obj.cover and obj.cover.photo:
return format_html(
'<img src="{}" style="max-width: 300px; height: auto;"/>',
obj.cover.photo_sm.url,
)
return "No cover image available"
cover_preview.short_description = "Cover Preview"
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""
Suodattaa 'cover'-valinnan niin, että se näyttää vain albumiin kuuluvat kuvat.
Uuden albumin luonnissa vaihtoehto pidetään tyhjänä.
"""
if db_field.name == "cover":
# Jos albumia ollaan luomassa (ei pk:ta), ei anneta mitään vaihtoehtoja
if request.resolver_match.kwargs.get("object_id") is None:
kwargs["queryset"] = Photo.objects.none()
else:
# Haetaan vain nykyiseen albumiin kuuluvat kuvat
album_id = request.resolver_match.kwargs.get("object_id")
kwargs["queryset"] = Photo.objects.filter(album_id=album_id)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
# 🔹 PhotoAdmin kuvien hallinta
class PhotoAdmin(admin.ModelAdmin):
list_display = ('slug', 'album', 'is_favorite', 'admin_thumbnail')
list_display_links = ('slug',)
search_fields = ('slug', 'photo')
readonly_fields = ['slug', 'taken_at', 'height', 'width', 'exif']
admin_thumbnail = AdminThumbnail(image_field=cached_admin_thumb)
list_filter = ('album',)
list_per_page = 30
list_editable = ('is_favorite',)
# 🔹 Rekisteröidään admin-paneeliin
admin.site.register(City, CityAdmin)
admin.site.register(Location, LocationAdmin)
admin.site.register(Album, AlbumAdmin)
admin.site.register(Photo, PhotoAdmin)
admin.site.register(Redir, RedirAdmin)