1

ImageFieldアップロード後にサイズを変更する必要があるモデルがあります。

class SomeModel(models.Model):
    banner = ImageField(upload_to='uploaded_images',
                        width_field='banner_width',
                        height_field='banner_height')
    banner_width = models.PositiveIntegerField(_('banner width'), editable=False)
    banner_height = models.PositiveIntegerField(_('banner height'), editable=False)

def save(self, *args, **kwargs):
    super(SomeModel, self).save(*args, **kwargs)
    resize_image(filename=self.banner.path,
                 width=MAX_BANNER_WIDTH,
                 height=MAX_BANNER_HEIGHT)

resize_imageはサイズ変更を行うカスタム関数であり、サイズ変更前にbanner_widthとbanner_heightに元の画像のサイズが入力されていることを除いて、すべてが正常に機能します。

サイズ変更された画像の実際のサイズは、指定されたMAX値よりも小さい場合があるため、サイズ変更後にサイズ変更されたファイルを開いて、実際のサイズを確認する必要があります。その後、手動で設定banner_widthbanner_heightて再度保存することもできますが、効率的な方法ではありません。最初にサイズ変更を行い、幅と高さのフィールドを設定してから保存することもできますが、self.banner.path保存が実行される前にその場所にファイルが存在しません。

これを適切に行う方法についての提案はありますか?

4

1 に答える 1

3

これを効率的に行うために数時間試みた後、私はこの問題へのアプローチを変更し、次CustomImageFieldのように定義しました。

class CustomImageField(ImageField):
    attr_class = CustomImageFieldFile

    def __init__(self, resize=False, to_width=None, to_height=None, force=True, *args, **kwargs):
        self.resize = resize
        if resize:
            self.to_width = to_width
            self.to_height = to_height
            self.force = force
        super(CustomImageField, self).__init__(*args, **kwargs)


class CustomImageFieldFile(ImageFieldFile): 

    def save(self, name, content, save=True):
        super(CustomImageFieldFile, self).save(name, content, save=save)
        if self.field.resize:
            resized_img = resize_image(filename=self.path,
                                       width=self.field.to_width,
                                       height=self.field.to_height,
                                       force=self.field.force)
            if resized_img:
                setattr(self.instance, self.field.width_field, resized_img.size[0])
                setattr(self.instance, self.field.height_field, resized_img.size[1])

今、私はただ定義することができます:

class SomeModel(models.Model):
    my_image = CustomImageField(resize=True, to_width=SOME_WIDTH, to_height=SOME_HEIGHT, force=False,
                                width_field='image_width', height_field='image_height')
    image_width = models.PositiveIntegerField(editable=False)
    image_height = models.PositiveIntegerField(editable=False)

また、resize引数によっては、アップロード後に画像のサイズを自動的に変更でき、オブジェクトを2回保存しなくても、幅/高さのフィールドが正しく更新されます。簡単なテストの後、正常に動作しているようです。

于 2012-03-27T21:26:32.853 に答える