【Django】ImageFieldをコピーして別ディレクトリに保存する方法

【Django】ImageFieldをコピーして別ディレクトリに保存する方法

こんばんはエンジニアの眠れない夜です。

今回はDjangoでImageモデルを保存する時に別の場所(モデル)にもコピーする方法の紹介です。
全く同じような使い方をするシーンはそれほどないと思うのでポイントだけ押さえて自分用にアレンジしてください。

ここでやっていることはImageImageCopyというモデルを作って、imageimage_copyというフォルダに分けて保存します。

保存するタイミングはform_valid()実行時です。

ImageFieldをコピーして別ディレクトリに保存する方法

保存する場所を指定する関数を作成

イメージを保存する場所をこの関数内で設定します。
filename[filename.rfind("."):]はファイル名を取り出しています。
その前にディレクトリをひっつけて画像保存時のパスを作っています。

def get_banner_path(instance,filename):
    return f'image/{filename[filename.rfind("."):]}'

def get_banner_copy_path(instance,filename):
    return f'image_copy/{filename[filename.rfind("."):]}'

それぞれのイメージモデルを作成

先程作成した関数をそれぞれのImageFieldのupdate_toにセットします。
この時()はつけずに関数名だけを入力します。

class MyImage(models.Model):
    image = models.ImageField(upload_to=get_image_path)

class MyImageCopy(models.Model):
    image = models.ImageField(upload_to=get_copy_image_path)

form_validでモデルの作成時にコピーを作成

CreateViewの中で実行する想定でいきます。UpdateViewでも同じようなことができます。
他のViewを使う時はform_valid以外のところで実行すれば同じことができます。

初めにMyImageから画像をContentFileを使ってコピーします。ここが今回の一番のポイントです。
後はファイル名を取り出して、新しいモデルにコピーしたイメージと名前をセットして保存するだけです。

from django.core.files.base import ContentFile

class CreateMyImage(CreateView):
    model = MyImage

 def form_valid(self, form):

    #get image and file name
    copy_image = ContentFile(form.instance.image.read())
    image_name = form.instance.image.name.split("/")[-1]

    # copy to new image model
    new_image = MyImageCopy(item=form.instance.item)
    new_image.image = copy_image
    new_image.image.name = image_name
    new_image.save()

まとめ

イメージモデルのupdate_toを別々のディレクトリを指定して

from django.core.files.base import ContentFileを使ってコピーする。

ほんとそれだけのことです(;´∀`)

忘れないようにわざわざ設定も含めて書いてみました。

とってもニッチな使い方かもしれませんがどこかの誰かのお役に立てると嬉しいです(^^)

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください