将生成的PIL图像保存到Django的ImageField中 [英] Save a generated PIL image into an ImageField in django
问题描述
我正在使用 qrcode 来生成qrcode.当购买票证或购买票证为真时,我想生成一个qrcode图像并使用PIL进行一些更改.最后,将修改后的画布保存到模型的图像"字段中.
I am using qrcode to generate qrcode. When a ticket is bought, or when bought is true, I would like to generate a qrcode image and make some changes using PIL. Finally save the modified canvas into the Image field of the model.
class Ticket(models.Model):
booked_at = models.DateTimeField(default=timezone.now)
qrcode_file = models.ImageField(upload_to='qrcode', blank=True, null=True)
bought = models.BooleanField(default=False)
def save(self, *args, **kwargs):
if self.bought:
...
...
qrcode_img = qrcode.make('some data')
canvas = Image.new('RGB', (total_width, total_height), 'white')
draw = ImageDraw.Draw(canvas)
position = (left, top)
canvas.paste(qrcode_img, position)
self.qrcode_file = canvas
self.booked_at = timezone.now()
super(Ticket, self).save(*args, **kwargs)
canvas.close()
qrcode_img.close()
else:
self.booked_at = timezone.now()
super(Ticket, self).save(*args, **kwargs)
但这会引发错误:
AttributeError:图像"对象没有属性"_committed"
AttributeError: 'Image' object has no attribute '_committed'
如何将生成的PIL图像保存到Django的ImageField中?
How can I save a generated PIL image into an ImageField in django?
推荐答案
您可以使用BytesIO将Pillow文件保存到内存中的Blob.然后创建一个File
对象,并将其传递给模型实例ImageField的save
方法.
You can use a BytesIO to save the Pillow file to an in-memory blob. Then create a File
object and pass that to your model instance ImageField's save
method.
from io import BytesIO
from django.core.files import File
canvas = Image.new('RGB', (total_width, total_height), 'white')
...
blob = BytesIO()
canvas.save(blob, 'JPEG')
self.qrcode_file.save('ticket-filename.jpg', File(blob), save=False)
查看django文档中的File
对象.
https://docs.djangoproject.com/zh-CN 2.0/ref/files/file/#the-file-object
Check out the django documentation for the File
object.
https://docs.djangoproject.com/en/2.0/ref/files/file/#the-file-object
您必须使用save=False
,因为默认的save=True
表示保存图像后将调用父模型的save
方法.您不希望在这里进行递归,因为您通常会陷入无限循环.
You have to use save=False
, since the default save=True
means that the parent model's save
method would be called after the image is saved. You don't want recursion here, since you would typically end up in an infinite loop.
这篇关于将生成的PIL图像保存到Django的ImageField中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!