【Django】関数で動的に保存先・保存名を指定する【FileField、ImageField】

django complicatedDjango

(最終更新月:2021年11月)

✓こんな方へ向けての記事となります

「FileField、ImageFieldで自動でタイトル名を生成し保存したい!」

「動的にファイル名を作成し保存したい!」

✓当記事を通じて伝えること

  • 保存先・ファイル名を関数で動的に指定する方法

通常、FileFiledで保存先を指定する場合は下記の通りです。

FileField(upload_to=”保存先のファイルパス”)

具体的な保存場所としては、settings.pyのMEDIA_ROOTで指定するフォルダ直下となります。

また、保存されるファイル名アップロードするファイル名をそのまま引き継ぐ形となります。

当記事では、下記のステップで関数を使って保存していきます。

  • モデルインスタンスに保存されたCharFieldを受け取る
  • CharFieldの値を保存名とする

順を追って見てきましょう。

※当記事ではFileFieldで説明をしていますが、ImageFieldの場合も同様のやり方になります。

✔月9,800円でWebデザインが学べる

デザナルは、Webデザインに苦手意識がある方におすすめのサブスク型スクールです。

特徴は以下の通り。

  • 初期費用不要
  • 教材が使い放題
  • 案件で収入も得られる

デザナルは稼ぎながら学べる、格安のWebデザインスクールです。

>>詳細はこちら<<

安いWebデザインスクール「デザナル」を徹底分析

はじめに

既にファイルを扱っていて、MEDIA_ROOTの設定ができている方は次章へお進みください

「まだ設定が終わってない!」という方は、settings.py内に下記を追記します

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media_local'

MEDIAファイルの保存先は「media_local」というフォルダ名にしました

お好きなフォルダ名にして頂いて構いません

今回使用するモデルクラス

今回使用するモデルクラスは、簡易的なものとし、フィールド「タイトル」と「ファイル」の2つで構成されています。

class FileSavingClass(models.Model):
    title = models.CharField(max_length=100)
    file = models.FileField(upload_to=savePath)

    def __str__(self):
        return self.title

FileFieldの引数で「upload_to=」にsavePathを代入しています

次章で「savePath」関数を作っていきます

「savePath」関数の作成と解説

savePathでは、

  1. CharField「title」に保存された値をファイル名とし、
  2. MEDIA_ROOTで指定したフォルダ直下の「files」というフォルダに保存する

ための文字列を返しています

def savePath(instance, filename):
    ext = filename.split('.')[-1]
    new_name = instance.title + "_saved"
    return f'files/{new_name}.{ext}'

一つ一つ解説します

【1行目】

def savePath(instance, filename):

引数として、「instance」と「filename」を受け取ります

  • 「instance」は保存されるモデルクラスのオブジェクトそのもの
  • 「filename」はアップロードされるファイル名

が代入されます

【2行目】

ext = filename.split('.')[-1]

「filename」には拡張子も含めたファイル名が格納されています

splitメソッドで、拡張子だけ取り出しています

【3行目】

new_name = instance.title + "_saved"

「instance」にはモデルクラスオブジェクトが格納されているので、

instance.title + “_saved”

で、タイトルフィールドに入力した値_savedというファイル名で保存されるよう文字列を作っています

【4行目】

return f'files/{new_name}.{ext}'

ファイル名を含めたファイルパス を返します

MEDIA_ROOTで指定したフォルダ以下のパスを文字列で記述します

この場合だと、「files」フォルダ内に保存するよう指示しています

フォルダの作成する

今回は2つフォルダを作成する必要があります

  1. MEDIA_ROOTの通り、「media_local
  2. savePath関数の通り、「media_local」内に「files」を作成

【フォルダツリー】

media_local
    └── files #ここにファイルが保存されていきます

まとめ

流れをまとめます

  1. settings.pyでMEDIA_ROOTを設定する
  2. フィールドの引数で「upload_to=関数名」とする
  3. 関数では、ファイルパス を返す
  4. MEDIA_ROOT、関数で指定した通りにフォルダを作成する

関数が増えてきた場合などは、別ファイルにまとめてインポートする方法を使っても良いと思います

以上、ファイルの保存先を関数で動的に指定する方法、でした!

当ブログでは、日報アプリ開発を通じて、Webアプリを一から開発し公開するまでを初学者の方でもわかるようにと記事を連載しています

「Djangoでのアプリ開発を学びたい!」
「Djangoで開発したアプリをWebで公開するにはどうするの?」

という方は必見です!

【Django】チュートリアル|日報アプリの開発から公開まで
Djangoのチュートリアルをお探しですか?具体的に「手を動かして作ってみたい!」という方へ向けて、誰でもできる簡易的な日報アプリの開発を通じて、Djangoの様々な機能に触れていくシリーズとなっています。PythonでWebアプリを作りたい方、必見の記事となります!

タイトルとURLをコピーしました