暂时我在Django 1.4上。我试图找出一种方法将图像字段从一个对象复制到另一个对象,而不会触及文件系统来获取高度和宽度。如果它是相关的,则源和目标对象具有不同的模型。我感兴趣的原因是我使用S3作为存储后端,这比简单的磁盘命中更麻烦。
通常,如果我说:
obj2.image = obj1.image
它将从FS获取文件,找出宽度和高度,并将它们保存到指定的宽度和高度字段。但是,原则上我认为我应该说:
obj2.image_width = obj1.image_width
obj2.image_height = obj1.image_height
obj2.image = obj1.image
事实上,我认为Django本身可以在没有抓取文件的情况下做到这一点。也许它在1.4之后的某些版本中会这样做。
我一直在玩它很多,看着Django来源,并了解它何时发生的怪癖。 update_dimension_fields
是有问题的函数,it's called with force=True
in ImageFileDescriptor.__set__
.
我发现如何部分避免它的一种方法是:
obj2.image = obj1.image
obj3.image = obj1.image
obj4.image = obj1.image
...
即它只是第一次点击文件系统。但当然它第一次仍然不必要地打它,而且这对请求之间没有任何帮助。我想到的另一件事是:
Model.objects.filter(pk=obj2.pk).update(
image=obj1.image,
image_width=obj1.image_width,
image_height=obj2.image_height
)
这只会起作用,因为就ORM的安全性而言,它是愚蠢的。除非我想在ModelForm中执行此操作,否则我会使用它。这意味着我必须覆盖save
函数:
def save(self, *args, **kwargs):
obj = super(MyModelForm, self).save(*args, **kwargs)
Model.objects.filter(pk=obj.pk).update( # extra query!
image=source.image,
image_width=source.image_width,
image_height=source.image_height
)
return Model.objects.get(pk=obj.pk) # another extra query!
问题是两个额外的查询,只是为了解决框架怪癖。第二个额外的查询是obj.image是预期的图像,对于消耗表单的任何东西。如果我100%确定表单消费者不需要它,我可以跳过它,这不是一个好主意。
那么有办法解决这个问题吗?是否有一个很好的安全问题,我没想到,这就解释了为什么我