Django Storages S3获取每个查询中的所有图像

时间:2013-02-18 12:52:47

标签: django amazon-s3 boto

我设置我的项目使用django-storage与S3Boto后端使用amazon S3。我的模型的Somo有ImageFields上传到S3,它工作正常。

当我尝试使用all()或filter()执行QuerySet时出现问题。对于每个请求,包括django-admin,django都会从服务器获取查询集中的每个图像。

我做的唯一更改是将 width_field height_field 添加到ImageField以保存高度和宽度,因此我无需从S3检索图像以获取此信息资讯

如果有人知道为什么会发生这种情况或者如何调试它,那将会非常有用。我一直在寻找S3Boto的代码,我不知道该检查什么。

1 个答案:

答案 0 :(得分:0)

对图像文件的这些访问可能来自django.db.models.fields.files.ImageField.update_dimension_fields

以下是它的描述:

"""
Updates field's width and height fields, if defined.

This method is hooked up to model's post_init signal to update
dimensions after instantiating a model instance.  However, dimensions
won't be updated if the dimensions fields are already populated.  This
avoids unnecessary recalculation when loading an object from the
database.

Dimensions can be forced to update with force=True, which is how
ImageFileDescriptor.__set__ calls this method.
"""    

在您的情况下,我要做的是角色我们自己的width_field和height_field,并在图片上传时仅更新一次。以下是我将如何实现它(尚未使用S3进行生产测试,但使用本地存储):

class ImageCovered(models.Model):
    def __init__(self, *args, **kwargs):
        # read and store original image data
        super(ImageCovered, self).__init__(*args, **kwargs)
        self.__original_cover_image = self.cover_image

    cover_image = models.ImageField(upload_to=get_upload_path, max_length=200, null=True, blank=True,)
    # We should not use ImageField's width_field nor height_field here, since it might call S3 files.
    # Instead, we implement our own fields and update it once only upon image saving.
    cover_image_height = models.PositiveSmallIntegerField(default=0)
    cover_image_width = models.PositiveSmallIntegerField(default=0)

    def save(self):
        super(ImageCovered, self).save()
        # Check if cover_image has been changed
        if self.__original_cover_image != self.cover_image :
            self.cover_image_height = self.cover_image.height
            self.cover_image_width = self.cover_image.width
            self.__original_cover_image = self.cover_image #replace original data
            super(ImageCovered, self).save(update_fields=('cover_image_height', 'cover_image_width',))