Django保存重写ImageField处理 [英] Django save override ImageField handling
问题描述
在此线程发生问题后,有当我使用Django Admin时,我的models.py仍然是个大问题。这是我的代码(我删除了与我的问题无关的东西):
After the problems I had on this thread, there is still a big problem in my models.py when I'm using the Django Admin. Here is my code (I removed stuff non related to my problem) :
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)
它的工作原理是,文件上传,调整大小,并在需要时成功转换为JPEG。这个问题,每当我编辑它,即使没有上传新的图像,它也会创建一个新的图像(例如,我第一次使用图像hello.jpg保存我的模型,然后编辑它,它会创建即使我没有上传任何东西,也称为hello_1.jpg。
我以为try / except块只能在编辑时工作(所以没有新的文件上传),但显然不是。
It works, the files are uploaded, resized and converted to JPEG successfully when needed. The problem, every time I edit it, even when NOT uploading a new image, it creates a new image (for example, I save my model a first time with image "hello.jpg", then I edit it, it'll create a new image called "hello_1.jpg" even if I didn't upload anything). I thought the try/except block would work when only editing (so no new file upload), but apparently not.
提前感谢帮助: )
推荐答案
为我工作的最终解决方案:
Final solution, working for me :
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)
希望可以帮助某人;)
这篇关于Django保存重写ImageField处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!