muistox/gallery/models/photo.py

66 lines
2.9 KiB
Python

import os
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 gallery.exif import Exif
from gallery.models import Album
class Photo(models.Model):
def _get_upload_path(instance, filename):
return os.path.join('albums', str(instance.album.slug), filename)
def _generate_unique_slug(self, datetime_taken=datetime.now()):
slug = int(datetime_taken.strftime('%y%m%d%H%M%S'))
while Photo.objects.filter(album=self.album, slug=slug).exists():
slug += 1
return str(slug)
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})
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")
exif = models.JSONField(blank=True, null=True, editable=False, verbose_name="Exif Metadata")
is_favorite = models.BooleanField(default=False, verbose_name="Is Favorite")
views = models.PositiveIntegerField(default=0, verbose_name="Views")
likes = models.PositiveIntegerField(default=0, verbose_name="Likes")
def add_like(self):
self.likes += 1
self.save()
def add_view(self):
self.views += 1
self.save()
def get_next(self):
return self.__class__.objects.filter(taken_at__gt=self.taken_at, album=self.album.id).order_by('taken_at').first()
def get_prev(self):
return self.__class__.objects.filter(taken_at__lt=self.taken_at, album=self.album.id).order_by('-taken_at').first()
def save(self, *args, **kwargs):
self.exif_data = Exif(self.photo.path)
datetime_taken = getattr(self.exif_data, 'datetimeoriginal', datetime.now)()
self.slug = self.slug or self._generate_unique_slug(datetime_taken)
self.taken_at = self.taken_at or datetime_taken
self.exif = getattr(self.exif_data, 'data', None)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('gallery:photo_url', kwargs={'album_slug': self.album.slug, 'photo_slug': self.slug})
def __str__(self):
return f'{self.slug} ({self.album.name})'