DjangoのFileField/ImageFieldのアップロード先のファイル名を変更する

DjangoのモデルでFileFieldやImageFieldを利用した場合, upload_toでアップロードされたファイルを保存するディレクトリを変更できますが, upload_toに関数を渡すことによって保存するファイル名も変更できます.

公式ドキュメントに記載があるように, 2つの引数をとり, ファイルへのパスを返す関数を定義し, これをupload_toに与えることで, 任意のファイル名で保存することが出来ます. 使用例を以下に示します.

import hashlib
import os.path
from django.db import models

def get_image_path(instance, filename):
    return "images/%s%s" % (hashlib.sha1(instance.title + filename).hexdigest(), os.path.splitext(filename)[1])

class Sample(models.Model):
    title = models.CharField(max_length=256)
    image = models.ImageField(upload_to=get_image_path)

get_image_pathはinstanceとfilenameの2つの引数を取ります. instanceにはFileFieldやImageFieldが定義されたモデルのインスタンスが与えられます.filenameにはアップロードされたファイルのファイル名が与えられます. ここでは, モデルのtitleフィールドとファイル名からハッシュ値を求め, 拡張子を付加したものをアップロード先のファイル名としています. get_image_pathはMEDIA_ROOTからの相対パスを返すようにします.