复制ImageField的内容时是否有任何干净的方法来避免命中文件系统?

时间:2014-03-06 19:58:20

标签: django image orm

暂时我在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%确定表单消费者不需要它,我可以跳过它,这不是一个好主意。

那么有办法解决这个问题吗?是否有一个很好的安全问题,我没想到,这就解释了为什么我

0 个答案:

没有答案