#!/usr/bin/env python # -*- coding: utf-8 -*- ''' (Data)models which describe the structure of data to be saved into database. ''' 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): """ PlaceImage defines an image file object that points to a file in uploads/. Intermediate image sizes are generated as defined in SIZES. PlaceImage references a Place to which it belongs. """ 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)