muistox/gallery/models.py

98 lines
3.8 KiB
Python

import os
from datetime import datetime, timedelta
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
from PIL import Image
from gallery.exif import Exif
# Create your models here.
class City(models.Model):
name = models.CharField(max_length=150, unique=True, verbose_name="City")
class Meta:
verbose_name_plural = "Cities"
def __str__(self):
return '{}'.format(self.name)
class Location(models.Model):
place = models.CharField(max_length=250, blank=True, null=False, verbose_name="Place")
city = models.ForeignKey(City, on_delete=models.CASCADE, related_name='places', verbose_name="City")
class Meta:
verbose_name_plural = "Locations"
unique_together = ('place', "city")
def __str__(self):
if self.place:
return '{0}, {1}'.format(self.city, self.place)
else:
return '{}'.format(self.city)
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")
is_public = models.BooleanField(default=False, verbose_name="Published")
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"
def __str__(self):
return '{}'.format(self.name)
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=None):
datetime_taken = datetime_taken or datetime.now()
slug = datetime_taken.strftime('%y%m%d%H%M%S')
counter = 0
while Photo.objects.filter(album=self.album, slug=slug).exists():
counter += 1
slug = (datetime_taken + timedelta(seconds=counter)).strftime('%y%m%d%H%M%S')
return 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_thumbnail = ImageSpecField(source='photo', processors=[ResizeToFill(100, 100)], format='JPEG', options={'quality': 70})
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")
def save(self, *args, **kwargs):
self.exif_data = Exif(self.photo.file)
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_path': self.album.slug, 'photo_slug': self.slug})
def __str__(self):
return f'{self.slug} ({self.album.name})'