from datetime import datetime from math import floor from django.core.cache import cache from django.core.exceptions import ValidationError from django.db import models from django.db.models import Sum from django.db.models.signals import post_save from django.dispatch import receiver 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") def _cache_key(self, suffix): return f'album_{self.pk}_{suffix}' @property def photos_in_album(self): key = self._cache_key('photo_count') count = cache.get(key) if count is None: count = self.photos.count() cache.set(key, count, 60 * 60 * 24) # Cache 24 h return count @property def photos_views(self): key = self._cache_key('photo_views') views = cache.get(key) if views is None: views = self.photos.aggregate(total_views=Sum('views'))['total_views'] or 0 cache.set(key, views, 60 * 5) # Cache 5 min return views 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) @receiver(post_save, sender=Album) def delete_album_cover_cache(sender, instance, **kwargs): cache.delete(f'cover_image_data_{instance.pk}')