import os import uuid from django.db import models from django.dispatch import receiver from django.contrib.auth.models import AbstractUser from django_thumbs.fields import ImageThumbsField # Create your models here. class Explorer(AbstractUser): """ Custom user model Addtional fields wbd """ def __str__(self): return self.username class Place (models.Model): """ Place defines a lost place (location, name, description etc.). """ name = models.CharField(max_length=50) submitted_by = models.ForeignKey( Explorer, on_delete=models.SET_NULL, null=True, blank=True, related_name='places' ) location = models.CharField(max_length=50) latitude = models.FloatField() longitude = models.FloatField() description = models.TextField() def __str__(self): return self.name def generate_image_upload_path(instance, filename): """ Callback for generating path for uploaded images """ return 'places/' + str(uuid.uuid4())+'.'+filename.split('.')[-1] class PlaceImage (models.Model): SIZES=( {'code': 'thumbnail', 'wxh': '390x390'}, {'code': 'hero', 'wxh': '700x700'}, {'code': 'large', 'wxh': '1920x1920'} ) description = models.TextField(blank=True) filename = ImageThumbsField( upload_to=generate_image_upload_path, max_length=50, sizes=SIZES ) place = models.ForeignKey( Place, on_delete=models.CASCADE, related_name='images' ) submitted_by = models.ForeignKey( Explorer, on_delete=models.SET_NULL, null=True, blank=True, related_name='images' ) def __str__(self): """ Returning the name of the corresponding place + id of this image as textual represntation of this instance """ return ' '.join([self.place.name, str(self.pk)]) # These two auto-delete files from filesystem when they are unneeded: @receiver(models.signals.post_delete, sender=PlaceImage) def auto_delete_file_on_delete(sender, instance, **kwargs): """ Deletes file from filesystem when corresponding `PlaceImage` object is deleted. """ if instance.filename: if os.path.isfile(instance.filename.path): os.remove(instance.filename.path) @receiver(models.signals.pre_save, sender=PlaceImage) def auto_delete_file_on_change(sender, instance, **kwargs): """ Deletes old file from filesystem when corresponding `PlaceImage` object is updated with new file. """ if not instance.pk: return False try: old_file = PlaceImage.objects.get(pk=instance.pk).filename except PlaceImage.DoesNotExist: return False new_file = instance.filename if not old_file == new_file: if os.path.isfile(old_file.path): os.remove(old_file.path)