画像ファイルへのこれらのアクセスは、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',))