theme template site personalizar password bootstrap django django-admin django-models

template - django-admin command



Django save anula el manejo de ImageField (2)

Después de los problemas que tuve en este hilo , todavía hay un gran problema en mi models.py cuando estoy usando el Administrador de Django. Aquí está mi código (eliminé cosas no relacionadas con mi problema):

from django.core.files.uploadedfile import InMemoryUploadedFile from PIL import Image as Img import StringIO class Mymodel(models.Model): photo = models.ImageField(upload_to="photo/", blank=True, null=True) def save(self, *args, **kwargs): width = 500 height = 500 size = (width,height) if self.photo: image = Img.open(StringIO.StringIO(self.photo.read())) (imw, imh) = image.size if (imw>width) or (imh>height) : image.thumbnail(size, Img.ANTIALIAS) #If RGBA, convert transparency if image.mode == "RGBA": image.load() background = Img.new("RGB", image.size, (255, 255, 255)) background.paste(image, mask=image.split()[3]) #3 is alpha channel image=background output = StringIO.StringIO() image.save(output, format=''JPEG'', quality=60) output.seek(0) self.photo = InMemoryUploadedFile(output,''ImageField'', "%s.jpg" %self.photo_principale.name.split(''.'')[0], ''image/jpeg'', output.len, None) try: this = Mymodel.objects.get(id=self.id) if this.photo != self.photo: this.photo.delete(save=False) except: pass # when new photo then we do nothing, normal case super(Mymodel, self).save(*args, **kwargs)

Funciona, los archivos se cargan, cambian de tamaño y se convierten a JPEG con éxito cuando sea necesario. El problema, cada vez que lo edito, incluso cuando NO se carga una imagen nueva, crea una nueva imagen (por ejemplo, guardo mi modelo por primera vez con la imagen "hello.jpg", luego lo edito, creará una nueva imagen llamada "hello_1.jpg" incluso si no subí nada). Pensé que el bloque try / except funcionaría solo cuando se editara (por lo que no hay carga de archivos nuevos), pero aparentemente no.

Gracias de antemano por la ayuda :)


Solución final, que funciona para mí:

from django.core.files.uploadedfile import InMemoryUploadedFile from PIL import Image as Img import StringIO from django.db.models.signals import post_delete from django.dispatch import receiver Class Mymodel(models.Model): photo= models.ImageField(upload_to="photo/", blank=True, null=True) def save(self, *args, **kwargs): width = 500 height = 500 size = (width,height) isSame = False if self.photo: try: this = Mymodel.objects.get(id=self.id) if this.photo==self.photo : isSame= True except: pass # when new photo then we do nothing, normal case image = Img.open(StringIO.StringIO(self.photo.read())) (imw, imh) = image.size if (imw>width) or (imh>height) : image.thumbnail(size, Img.ANTIALIAS) #If RGBA, convert transparency if image.mode == "RGBA": image.load() background = Img.new("RGB", image.size, (255, 255, 255)) background.paste(image, mask=image.split()[3]) # 3 is the alpha channel image=background output = StringIO.StringIO() image.save(output, format=''JPEG'', quality=60) output.seek(0) self.photo = InMemoryUploadedFile(output,''ImageField'', "%s.jpg" %self.photo.name.split(''.'')[0], ''image/jpeg'', output.len, None) try: this = Mymodel.objects.get(id=self.id) if this.photo==self.photo or isSame : self.photo=this.photo else : this.photo.delete(save=False) except: pass # when new photo then we do nothing, normal case super(Mymodel, self).save(*args, **kwargs) @receiver(post_delete, sender=Mymodel) def photo_post_delete_handler(sender, **kwargs): instance = kwargs[''instance''] storage, path = instance.photo.storage, instance.photo.path if (path!=''.'') and (path!=''/'') and (path!=''photo/'') and (path!=''photo/.''): storage.delete(path)

Espero que pueda ayudar a alguien;)


Tratar:

if self.photo.name != '''':

o

if self.photo.size > 0: