3

親オブジェクト (ForeignKey) 間でサムネイルの幅が異なるモデルがあります。この情報をイメージキット プロセッサに供給できる必要があります。これは私が持っているものです:

class Wall(models.Model):
    #...
    width = models.SmallIntegerField(null=True, blank=True)
    #...


class Poster(models.Model):
    wall = models.ForeignKey(Wall, related_name='posters')
    #...
    original_image = models.ImageField(upload_to=upload_image_to)

    def __init__(self, *args, **kwargs):
        self.thumbnail = ImageSpecField([
                Adjust(contrast=1.2, sharpness=1.1),
                SmartResize(height=163, width=self.wall.width)
            ],
            image_field='original_image', format='PNG'
        )

        super(Poster, self).__init__(*args, **kwargs)
    #...

しかし、これを行っても何も起こらず、サムネイルの URL も生成されません。

そして、次の例外が発生します:
AttributeError: 'ForeignKey' object has no attribute 'width'

class Poster(models.Model):
    wall = models.ForeignKey(Wall, related_name='posters')
    #...
    original_image = models.ImageField(upload_to=upload_image_to)

    thumbnail = ImageSpecField([
            Adjust(contrast=1.2, sharpness=1.1),
            SmartResize(height=163, width=wall.width)
        ],
        image_field='original_image', format='PNG'
    )
    #...
4

2 に答える 2

6

#1 の回答は、現在のバージョンの django-imagekit (3.0.3) には適合しません。そして、公式の解決策を見つけました。http://django-imagekit.readthedocs.org/en/latest/advanced_usage.html#specs-that-c​​hangeを参照してください

于 2013-10-09T07:58:54.013 に答える
4

モデル定義でインスタンス値を参照することはできません。これは、Django で少しトリッキーになるところです。モデルは、インスタンス化されたときにインスタンスがどのように見えるかの宣言です。これが、相互に依存するフィールドがimage_field='original_image'仕様などの名前で他のフィールドを参照する必要がある理由です。

imagekit のソースを見ると、processors適用する静的プロセッサのリストを取得するか、生成時に適用するプロセッサのリストを返す呼び出し可能オブジェクトを取得できることがわかります。幅に基づいて実行時に世代を変更する必要があるため、これを有利に使用できます。

processorscallable は、フィールドが表示されるインスタンスで呼び出され、thumbnail幅のルックアップを行うことができます。

def thumbnail_processors(instance, file):
    # Dynamic width lookup.
    width = instance.wall.width
    return [
        Adjust(contrast=1.2, sharpness=1.1),
        SmartResize(width=width, height=163),
        ]


class Poster(models.Model):
    wall = models.ForeignKey(Wall, related_name='posters')
    #...
    original_image = models.ImageField(upload_to=upload_image_to)

    thumbnail = ImageSpecField(
        processors=thumbnail_processors,
        image_field='original_image', format='PNG'
    )
    #...

フィールドにアクセスするthumbnail_processorsと、モデル宣言時ではなく、実行時にプロセッサのリストを取得するために呼び出されます。はwidth外部キーから取得され、適切なサイズ変更が実行されます。

おそらく、調査が必要な落とし穴がいくつかあります。画像ファイルにアクセスするthumbnailと、幅に応じて画像ファイルが生成されます。後で幅を変更してサムネイルを再度リクエストすると、ストレージとキャッシュのバックエンドがどのように動作するかわかりません。サムネイルの幅をエンコードできるカスタム ファイル名ジェネレーターが必要になる可能性があります。これにより、幅が変更されたときに新しいサムネイルが別の名前で生成されます。

于 2013-01-25T03:45:31.417 に答える