django - 在 Django 中,如何使用接收器替换模型的图像?
问题描述
我正在尝试将作为模型的一部分上传的图像转换为保存时的 jpgs。我的代码创建了 jpg 并删除了原始图像(wg,tiff),但我无法用它来替换模型中的图像。换句话说,如果我创建一个项目 x 并尝试显示 x.image,则什么都没有。任何帮助将不胜感激!
模型.py:
def image_upload(instance, filename):
ext = filename.split('.')[-1]
filename = "{0}.{1}".format(instance.title, ext)
return os.path.join("originals", filename)
class Item(models.Model):
id = models.AutoField(primary_key=True)
owner = models.ForeignKey(
get_user_model(),
on_delete=models.SET_NULL,
null=True,
blank=True
)
title = models.CharField(max_length=200)
image = models.ImageField(
upload_to=image_upload,
blank=True,
validators=[validate_image]
)
@receiver(post_save, sender=Item)
def image_to_jpg(sender, instance, **kwargs):
if kwargs.get('created') and instance.image:
filename, file_ext = os.path.splitext(instance.image.path)
if file_ext != ".jpg":
im = Image.open(instance.image.path)
im = im.convert("RGB")
im.save(instance.image.path.replace(file_ext, ".jpg"))
storage, path = instance.image.storage, instance.image.path
instance.image = im
storage.delete(path)
解决方案
我建议你看看Django ImageKit library。它会在上传时为您处理将图像处理为一种格式的逻辑。对于您的模型,您只需执行以下操作:
class Item(models.Model):
id = models.AutoField(primary_key=True)
owner = models.ForeignKey(get_user_model(),on_delete=models.SET_NULL, null=True, blank=True)
title = models.CharField(max_length=200)
image = ProcessedImageField(
upload_to=image_upload,
blank=True,
validators=[validate_image], format='JPEG', options={'quality': 80}
)
在文档中,您还可以看到它们提供的一组不同的内置处理器,例如用于调整图像大小以适应最大分辨率。
对于您的具体答案,我认为问题只是图像字段的更改没有保存在数据库中......您需要:
- 停用
post_save
信号并呼叫instance.save()
,然后再次激活 - 使用模型的
update()
方法
但我认为 ImageKit 选项更健壮且经过良好测试。
推荐阅读
- spring - ProjectionOperation plus和previousOperation聚合mongodb java
- excel - Range类的间歇性“运行时错误'1004'PasteSpecial方法失败
- ruby-on-rails - 复杂 Rails 表单最佳实践
- database - Kusto 查询列上的优先排序
- java - 如何在 groovy 或 java 中保存 dbf 文件?
- c++ - 我可以打印到始终显示的 Windows 控制台数据吗?
- typescript - typescript-eslint 检查是否所有变量都分配了数据类型
- python - 创建火车和测试数据加载器
- python - 列出 setup.py 中已安装的软件包
- mysql - MySQL Select 和 IF() 语句