【发布时间】:2020-10-25 13:56:56
【问题描述】:
我的应用程序需要保存上传图片的多个版本。一张高质量图像和另一张仅用于缩略图(低质量)。 目前这大部分时间都在工作,但有时保存方法会失败,并且我的所有缩略图都被删除,尤其是当我在表单中使用 remove_cover 复选框时
raise ValueError("'%s' 属性没有与之关联的文件。" % self.field.name) 应用程序 |值错误: “postcover_tn”属性没有与之关联的文件。
-> 在此处查看完整跟踪:https://pastebin.com/hgieMGet
models.py
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField()
content = models.TextField(blank=False)
postcover = models.ImageField(
verbose_name="Post Cover",
blank=True,
null=True,
upload_to=image_uploads,
)
postcover_tn = models.ImageField(
verbose_name="Post Cover Thumbnail",
blank=True,
null=True,
upload_to=image_uploads,
)
published_date = models.DateTimeField(auto_now_add=True, null=True)
def save(self, *args, **kwargs):
super(Post, self).save(*args, **kwargs)
if self.postcover:
if not (self.postcover_tn and os.path.exists(self.postcover_tn.path)):
image = Image.open(self.postcover)
outputIoStream = BytesIO()
baseheight = 500
hpercent = baseheight / image.size[1]
wsize = int(image.size[0] * hpercent)
imageTemproaryResized = image.resize((wsize, baseheight))
imageTemproaryResized.save(outputIoStream, format='PNG')
outputIoStream.seek(0)
self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
"%s.png" % self.postcover.name.split('.')[0], 'image/png',
sys.getsizeof(outputIoStream), None)
image = Image.open(self.postcover)
outputIoStream = BytesIO()
baseheight = 175
hpercent = baseheight / image.size[1]
wsize = int(image.size[0] * hpercent)
imageTemproaryResized = image.resize((wsize, baseheight))
imageTemproaryResized.save(outputIoStream, format='PNG')
outputIoStream.seek(0)
self.postcover_tn = InMemoryUploadedFile(outputIoStream, 'ImageField',
"%s.png" % self.postcover.name.split('.')[0], 'image/png',
sys.getsizeof(outputIoStream), None)
elif self.postcover_tn:
self.postcover_tn.delete()
super(Post, self).save(*args, **kwargs)
我似乎也无法正确解决:
- self.postcover_tn.delete() -> 类“InMemoryUploadedFile”的未解析属性引用“删除”
- self.postcover_tn.path -> 类“InMemoryUploadedFile”的未解析属性引用“路径”
forms.py:
def save(self, commit=True):
instance = super(PostForm, self).save(commit=False)
if self.cleaned_data.get('remove_cover'):
try:
os.unlink(instance.postcover.path)
except OSError:
pass
instance.postcover = None
if commit:
instance.save()
return instance
【问题讨论】:
-
您是否考虑过为此使用sorl_thumbnail?它将即时生成您需要的任何大小并将其缓存以供以后使用。与
ImageField一起使用。这样您就不必担心调整大小和保存错误。 -
并非如此,但对我来说,这看起来总是动态生成图像。如果是这样,这会伤害我的 CPU,因为我处理平台上的每个请求的图像。所以我认为在这里生成预处理图像是一个更好的选择。如果我错了,请纠正我。
-
它只生成一次,然后保存到缓存文件夹中。每次调用 image + size 时,它都会首先检查它是否存在。当我说的时候,我的意思是你可以使用模板标签设置来生成你想要的任何尺寸。
-
啊,好吧,谢谢你的建议:D。
-
但是在某种程度上,如果我想像 forms.py 中所示的那样删除一个后盖,这仍然不能解决我的问题,这仍然失败,或者至少它会取消所有后盖的链接,直到我保存一个新的某种原因。
标签: python django forms image modeling