我设置我的项目使用django-storage与S3Boto后端使用amazon S3。我的模型的Somo有ImageFields上传到S3,它工作正常。
当我尝试使用all()或filter()执行QuerySet时出现问题。对于每个请求,包括django-admin,django都会从服务器获取查询集中的每个图像。
我做的唯一更改是将 width_field 和 height_field 添加到ImageField以保存高度和宽度,因此我无需从S3检索图像以获取此信息资讯
如果有人知道为什么会发生这种情况或者如何调试它,那将会非常有用。我一直在寻找S3Boto的代码,我不知道该检查什么。
答案 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',))