0

我使用带有 S3Boto 后端的 django-storages 设置我的项目以使用亚马逊 S3。我的模型中的一些有上传到 S3 的 ImageFields,它工作正常。

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

我所做的唯一更改是将width_fieldheight_field添加到 ImageField 以保存高度和宽度,因此我不必从 S3 检索图像来获取此信息。

如果有人知道为什么会发生这种情况或如何调试它,那将非常有帮助。我一直在查看 S3Boto 的代码,但不确定要检查什么。

4

1 回答 1

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',))
于 2013-09-25T17:36:15.743 回答