2016-03-21 12 views
1

ImageFieldを保存するときに、アップロードした画像のサイズを変更、圧縮、最適化する方法を探しています。Django ImageFieldでモデルを保存するときにユーザーが画像ファイルをアップロードしたかどうかを確認する方法は?

class Image(models.Model): 
    name = models.CharField(max_length=254, blank=True) 
    caption = models.TextField(max_length=1000, blank=True) 
    height = models.IntegerField() 
    width = models.IntegerField() 
    image = models.ImageField(upload_to='', height_field='height', width_field='width', storage=S3MediaStorage()) 

私の最初の考えは上書きモデルのsave()、そこにこのロジックを実装することでしたが、私は、ユーザーが画像ファイルを更新しない場合、サイズ変更/圧縮/最適化を再度実行したくない(つまり、もし彼は既存のオブジェクトのnameまたはcaptionを更新して保存します)。

  1. ユーザーのみ例えば、モデル内の別のフィールドを変更したときに何ていない新しいイメージファイルがのImageFieldにアップロードされたときにチェックする適切な方法ですが、。ユーザーはcaptionを更新しますが、それ以外はそのままの状態にしていますか?

  2. アップロードされた画像ファイルはどのようにコードにアクセスできますか?私。ピローに渡すことができる実際のイメージファイルを含む変数は何ですか?

編集:これはthe suspected duplicateからユニークです。フィールドが変更されているかどうかを尋ねているわけではありません。なぜなら、それは常に誤検出を引き起こすからです。ユーザーがイメージファイルをアップロードしたかどうかを尋ねています。これは即座に変更(サイズ変更/最適化/圧縮)されるため、アップロードしたイメージをすぐにダウンロードすると、ランダムに生成されたファイル名でバイナリが異なるしたがって、ファイル名またはバイナリを比較することは、ユーザーが別のイメージをアップロードしているかどうかを判断する有効な方法ではありません。

+0

[Django:保存すると、フィールドが変更されたかどうかを確認するにはどうすればいいですか?](http://stackoverflow.com/questions/1355150/django-when-saving-how-can-you-check-あなたがこの問題を区別するための情報を追加しました。ありがとうございました – rnevius

答えて

1

お使いのモデルは別の名前を使用できます。謝罪:

それでも、あなたはpost_save信号(https://docs.djangoproject.com/en/1.9/ref/signals/#post-save

from PIL import Image 
from django.db.models.signals import post_save 

@receiver(post_save, sender=Image) 
def crop_image(sender, instance, **kwargs): 
    img = instance.image 
    original = Image.open(img.src.path) 
    # ... your code here... 

EDITを介して画像を操作してみてください。銃をちょっと飛ばした。あなたの実際の問題の1つは、イメージが同じであれば、イメージを操作しないことでした。私は上の別の答えを修正しています名前が変更された場合、あなたがヘルパーフィールドに元のファイル名を保存することができ

class Image(models.Model): 
    image = models.ImageField(upload_to='', height_field='height', width_field='width', storage=S3MediaStorage()) 

    __original_image_filename = None 

    def __init__(self, *args, **kwargs): 
     super(Image, self).__init__(*args, **kwargs) 
     self.__original_image_filename = self.image.name 

    def save(self, force_insert=False, force_update=False, *args, **kwargs): 
     if self.image.name != self.__original_image_filename: 
     # name changed - do something here 

     super(Image, self).save(force_insert, force_update, *args, **kwargs) 
     self.__original_image_filename = self.image.name 

def save(self, **kwargs): 
    try: 
     related_img = Image.objects.get(id=self.id) 
     if related_img.image != self.image: 
      crop_me(self.image) 
    except Image.DoesNotExist: 
     # object doesn't exist. Passing... 
     pass 

    return super(Image, self).save(**kwargs) 

def crop_me(img): 
    original_img = Image.open(img.src.path) 
    # ... your code here... 

EDIT 2:あなたは、この(未テスト)のようなsave()でそれを行うことができます飛行機で飛行機に乗ると、1〜 the original answerを確認してください。その質問にはあなたを助ける他の方法があります。

+1

あなたは 'if not self.id'を書いて、' if'ブロックの中に 'id = self .id'。それを修正したいかもしれない。それは 'もしself.id'であるべきです。 – xyres

+0

固定。それを指摘してくれてありがとう! –

+0

'if related_img.image!= self.image:'これは、 'related_img.image'でアップロードされた元のファイルですが、名前が変更された元のファイルのコピーをランダムな文字列に保存してイメージのサイズを変更して圧縮しただけではうまくいかないようです。ユーザーがイメージファイルをアップロードしたかどうかを確認するだけですか? – dtgq