web-dev-qa-db-ja.com

Djangoでアップロードされたファイルのファイル名を変更するにはどうすればよいですか?

アップロードされたファイルのファイル名をdjangoで変更することはできますか?検索したが答えが見つからなかった。

私の要件は、ファイルがアップロードされるたびに、そのファイル名を次の形式で変更する必要があることです。

format = userid + transaction_uuid + file_extension

どうもありがとうございました...

31

ファイルをどのようにアップロードしますか?私はFileFieldを想定しています。

FileField.upload_to のドキュメントには、upload_toフィールド、

ファイル名を含むアップロードパスを取得するために呼び出される関数などの呼び出し可能オブジェクトでもかまいません。この呼び出し可能オブジェクトは、2つの引数を受け入れ、ストレージシステムに渡されるUnix形式のパス(スラッシュを含む)を返す必要があります。渡される2つの引数は次のとおりです。

"instance":FileFieldが定義されているモデルのインスタンス。より具体的には、これは現在のファイルが添付されている特定のインスタンスです。

"filename":最初にファイルに付けられたファイル名。これは、最終的な宛先パスを決定するときに考慮される場合と考慮されない場合があります。

したがって、名前を処理してパスを返す関数を作成する必要があるようです。

def update_filename(instance, filename):
    path = "upload/path/"
    format = instance.userid + instance.transaction_uuid + instance.file_extension
    return os.path.join(path, format)
48
monkut

コールバックを呼び出すupload_toを含むFileFieldが必要です。[1]を参照してください

コールバックは、パラメーターの1つとしてインスタンスを取得し、もう1つとしてファイル名を取得するラッパーメソッドを呼び出す必要があります。 [2]

好きなように変更して、新しいパスを返します[3]

1.ロジック

FileField(..., upload_to=method_call(params),....)

2.メソッドを定義する

def method_call(params):
    return u'abc'

3.ラッパー:

def wrapper(instance, filename):
    return method

これは、インスタンスを取得するために必要なラッパーメソッドです。

def wrapper(instance, filename):
... Your logic
...
return wrapper

完全なコード

def path_and_rename(path, prefix):
    def wrapper(instance, filename):
        ext = filename.split('.')[-1]
        project = "pid_%s" % (instance.project.id,)
        # get filename
        if instance.pk:
            complaint_id = "cid_%s" % (instance.pk,)
            filename = '{}.{}.{}.{}'.format(prefix, project, complaint_id, ext)
        else:
            # set filename as random string
            random_id = "rid_%s" % (uuid4().hex,)
            filename = '{}.{}.{}.{}'.format(prefix, project, random_id, ext)
            # return the whole path to the file
        return os.path.join(path, filename)

    return wrapper

メソッドの呼び出し

sales_attach = models.FileField("Attachment", upload_to=path_and_rename("complaint_files", 'sales'), max_length=500,
                                help_text="Browse a file")

お役に立てれば。ありがとう。

6
A.J.

関数を再利用できるようにする場合:

import hashlib
import datetime
import os
from functools import partial

def _update_filename(instance, filename, path):
    path = path

    filename = "..."

    return os.path.join(path, filename)

def upload_to(path):
    return partial(_update_filename, path=path)

次のように使用するだけです。

document = models.FileField(upload_to=upload_to("my/path"))
5
nicolas

基本的な方法は

import os

os.rename('a.txt', 'b.html')

あなたの状況では、おそらく次のようになります

os.rename ("a.txt", "{id}{uuid}.{ext}".format(id=userid, uuid=transaction_uuid, ext=file_extension))
1
Bárbara Este