如何在Django上传图像时更改图像格式?

7
当用户在Django管理面板上传图片时,我想将图像格式更改为'.webp'。我已经重写了模型的save方法。Webp文件生成在media/banner文件夹中,但生成的文件未保存在数据库中。我该如何实现这个功能?
def save(self, *args, **kwargs):
    super(Banner, self).save(*args, **kwargs)
    im = Image.open(self.image.path).convert('RGB')
    name = 'Some File Name with .webp extention' 
    im.save(name, 'webp')
    self.image = im

但是在保存模型后,Image类的实例没有保存在数据库中吗?

我的模型类是:

class Banner(models.Model):
    image = models.ImageField(upload_to='banner')
    device_size = models.CharField(max_length=20, choices=Banner_Device_Choice)
2个回答

5
from django.core.files import ContentFile

如果您已经有了webp文件,请读取该文件,将其放入带有缓冲区的ContentFile()中(类似于io.BytesIO)。然后,您可以继续将ContentFile()对象保存到模型中。不要忘记更新模型字段并保存模型!

https://docs.djangoproject.com/en/4.1/ref/files/file/

或者

"django-webp-converter是一个Django应用程序,可以直接将静态图像转换为WebP图像,并在不支持的浏览器上回退到原始静态图像。"

它可能也具有一些保存功能。

https://django-webp-converter.readthedocs.io/en/latest/

原因

您也在错误的顺序中保存,正确的顺序是在最后调用 super().save()

编辑并测试过的解决方案:
from django.core.files import ContentFile
from io import BytesIO

def save(self, *args, **kwargs):
    #if not self.pk: #Assuming you don't want to do this literally every time an object is saved.
    img_io = BytesIO()
    im = Image.open(self.image).convert('RGB')
    im.save(img_io, format='WEBP')
    name="this_is_my_webp_file.webp"
    self.image = ContentFile(img_io.getvalue(), name)
    super(Banner, self).save(*args, **kwargs) #Not at start  anymore
    

    

1
我必须首先调用保存方法的原因是它显示了一个文件未找到的错误(Project_Path + file_name)。 - Manoj Kamble

0

你好,像这样做:

...
from django.db.models.signals import post_save
from django.dispatch import receiver

class Banner(models.Model):
    image = models.ImageField(upload_to='banner')
    device_size = models.CharField(max_length=20,choices=Banner_Device_Choice)
        
            
@receiver(post_save, sender=Banner)
def create_webp(sender, instance, created, **kwargs):
    path = instance.image.path
    if instance.image.path[-4:] !=webp:
        im = Image.open(path).convert('RGB')
        extention = instance.image.path.rsplit(".",2)[1]
        file_name = path.replace(extention,"webp") 
        im.save(file_name, 'webp')
        instance.image.path = file_name
        instance.save()

在设置instance.path时出现错误,显示为“无法设置属性'path'”。 - Manoj Kamble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接