diff --git a/gallery/admin.py b/gallery/admin.py index 4683ec7..8036d70 100644 --- a/gallery/admin.py +++ b/gallery/admin.py @@ -3,13 +3,13 @@ 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 ResizeToFill +from imagekit.processors import ResizeToFit from gallery.models import Album, City, Location, Photo class AdminThumbnailSpec(ImageSpec): - processors = [ResizeToFill(50, 50)] + processors = [ResizeToFit(100, 100)] format = 'JPEG' options = {'quality': 60} diff --git a/gallery/management/commands/regenerate_thumbnails.py b/gallery/management/commands/regenerate_thumbnails.py new file mode 100644 index 0000000..52b82a5 --- /dev/null +++ b/gallery/management/commands/regenerate_thumbnails.py @@ -0,0 +1,38 @@ +from django.core.management.base import BaseCommand +from imagekit.cachefiles import ImageCacheFile + +from gallery.models import Photo + + +class Command(BaseCommand): + help = 'Regenerate all thumbnails (photo_sm, photo_md, photo_bg)' + + def handle(self, *args, **kwargs): + photos = Photo.objects.all() + total = photos.count() + + for idx, photo in enumerate(photos, 1): + print(f"Processing {idx}/{total}: {photo.photo.name}") + + # Regenerate photo_sm + try: + photo.photo_sm.generate() + print(f" - photo_sm regenerated") + except Exception as e: + print(f" - Error generating photo_sm: {e}") + + # Regenerate photo_md + try: + photo.photo_md.generate() + print(f" - photo_md regenerated") + except Exception as e: + print(f" - Error generating photo_md: {e}") + + # Regenerate photo_bg + try: + photo.photo_bg.generate() + print(f" - photo_bg regenerated") + except Exception as e: + print(f" - Error generating photo_bg: {e}") + + print("Thumbnail regeneration completed!") diff --git a/gallery/models/photo.py b/gallery/models/photo.py index c49759e..143cfe9 100644 --- a/gallery/models/photo.py +++ b/gallery/models/photo.py @@ -4,7 +4,7 @@ from datetime import datetime from django.db import models from django.urls import reverse from imagekit.models import ImageSpecField -from imagekit.processors import ResizeToFill +from imagekit.processors import ResizeToFit from gallery.exif import Exif from gallery.models import Album @@ -24,9 +24,9 @@ class Photo(models.Model): album = models.ForeignKey(Album, on_delete=models.CASCADE, related_name='photos', verbose_name="Album") slug = models.CharField(max_length=15, editable=False, verbose_name="Photo Slug") photo = models.ImageField(upload_to=_get_upload_path, height_field='height', width_field='width', verbose_name="Photo") - photo_sm = ImageSpecField(source='photo', processors=[ResizeToFill(320, 320)], format='JPEG', options={'quality': 70}) - photo_md = ImageSpecField(source='photo', processors=[ResizeToFill(720, 720)], format='JPEG', options={'quality': 80}) - photo_bg = ImageSpecField(source='photo', processors=[ResizeToFill(1920, 1920)], format='JPEG', options={'quality': 90}) + photo_sm = ImageSpecField(source='photo', processors=[ResizeToFit(320, 320)], format='JPEG', options={'quality': 70}) + photo_md = ImageSpecField(source='photo', processors=[ResizeToFit(720, 720)], format='JPEG', options={'quality': 80}) + photo_bg = ImageSpecField(source='photo', processors=[ResizeToFit(1920, 1920)], format='JPEG', options={'quality': 90}) width = models.PositiveIntegerField(default=0, editable=False, verbose_name="Photo Width") height = models.PositiveIntegerField(default=0, editable=False, verbose_name="Photo Height") taken_at = models.DateTimeField(blank=True, null=True, editable=False, verbose_name="Taken at") @@ -60,6 +60,10 @@ class Photo(models.Model): def get_absolute_url(self): return reverse('gallery:photo_url', kwargs={'album_slug': self.album.slug, 'photo_slug': self.slug}) + + class Meta: + verbose_name_plural = "Photos" + ordering = ('-taken_at',) def __str__(self): return f'{self.slug} ({self.album.name})'