from datetime import datetime from math import floor from django.core.exceptions import ValidationError from django.db import models from django.templatetags.static import static from django.urls import reverse from django.utils.text import slugify from gallery.models.location import Location class Album(models.Model): name = models.CharField(max_length=150, unique=True, verbose_name="Album") slug = models.SlugField(max_length=150, unique=True, verbose_name="Slug") location = models.ForeignKey(Location, blank=True, null=True, on_delete=models.SET_NULL, related_name='albums', verbose_name="Location") album_date = models.DateField(default=datetime.now, verbose_name="Album Date") cover = models.ForeignKey("Photo", blank=True, null=True, on_delete=models.SET_NULL, related_name='cover_to', verbose_name="Album cover") is_public = models.BooleanField(default=False, verbose_name="Published") @property def photos_in_album(self): return self.photos.count() @property def photos_views(self): total_views = sum(self.photos.views()) return total_views @property def cover_image_data(self): def compute_size(photo, max_w=720, max_h=720): if not photo.width or not photo.height: return (None, None) aspect = photo.aspect_ratio if photo.width > photo.height: w = min(photo.width, max_w) h = floor(w / aspect) else: h = min(photo.height, max_h) w = floor(h * aspect) return (w, h) photo = self.cover or self.photos.order_by('-width').first() if photo: url = photo.photo_md.url w, h = compute_size(photo) return { "url": url, "width": w, "height": h, "aspect_ratio": round(photo.aspect_ratio, 3) } return { "url": static('img/placeholder.png'), "width": 1200, "height": 800, "aspect_ratio": 1.5 } def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) super(Album, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('gallery:album_url', kwargs={'album_slug': self.slug}) class Meta: verbose_name_plural = "Albums" ordering = ('album_date',) def __str__(self): return '{}'.format(self.name)