Djangoを使用して、アップロードされた写真をサーバー上で一意のファイル名に変更する最良の方法は何ですか?それぞれの名前が1回だけ使用されることを確認したいと思います。おそらくGUIDを使用して、これを実行できるpinaxアプリはありますか?
Uuidを使用します。これをモデルに関連付けるには、FileField upload_toの Djangoドキュメント を参照してください。
たとえば、models.pyで次の関数を定義します。
import uuid
import os
def get_file_path(instance, filename):
ext = filename.split('.')[-1]
filename = "%s.%s" % (uuid.uuid4(), ext)
return os.path.join('uploads/logos', filename)
次に、FileField/ImageFieldを定義するときに、get_file_path
値としてupload_to
を指定します。
file = models.FileField(upload_to=get_file_path,
null=True,
blank=True,
verbose_name=_(u'Contact list'))
より良い方法は、helpers.pyで共通のクラスを使用することです。この方法で、アプリ全体でランダムファイルジェネレーターを再利用できます。
あなたのhelpers.pyで:
import os
import uuid
from Django.utils.deconstruct import deconstructible
@deconstructible
class RandomFileName(object):
def __init__(self, path):
self.path = os.path.join(path, "%s%s")
def __call__(self, _, filename):
# @note It's up to the validators to check if it's the correct file type in name or if one even exist.
extension = os.path.splitext(filename)[1]
return self.path % (uuid.uuid4(), extension)
次に、モデルにヘルパークラスをインポートします。
from mymodule.helpers import RandomFileName
そしてそれを使います:
logo = models.ImageField(upload_to=RandomFileName('logos'))
参照: https://coderwall.com/p/hfgoiw/give-imagefield-uploads-a-unique-name-to-avoid-file-overwrites
Django 1.6.6、1.5.9、および1.4.14以前は、 get_avaialable_name
関数は、アンダースコアを追加することで、ファイルに自動的に一意の名前を付けます。たとえば、「test.jpg」というファイルと「test.jpg」という別のファイルをサーバーに保存すると、最初のファイルはtest.jpg、2番目のファイルはtest_1.jpgという名前になります。
悲しいかな、それはマシンにDDOSを実行するためのベクトルであることが判明しました。保存する数千のゼロバイトファイルを送信し、それぞれが数千の以前のファイルをチェックして名前を確認します。
ドキュメントを参照 のように、新しいシステムはこの問題を修正するためにアンダースコアの後に7つのランダムな数字を追加します。
この回答の執筆時点では、これを実現するために特別なことを行う必要はもうないようです。静的なupload_toプロパティを使用してFileFieldを設定すると、Djangoストレージシステムが自動的に命名を管理するため、重複したファイル名がアップロードされた場合、Djangoがランダムに複製の新しい一意のファイル名を生成します。
Django 1.10で動作します。
独自のFileField
を書いて上書きgenerate_filename
。
例えば:
class UniqueNameFileField(FileField):
def generate_filename(self, instance, filename):
_, ext = os.path.splitext(filename)
name = f'{uuid.uuid4().hex}{ext}'
return super().generate_filename(instance, name)
写真がアップロードされた日付/時刻とファイル名を連結し、次に hashlib を使用してメッセージダイジェストを作成しませんか?それはあなたにユニークなファイル名を与えるはずです。
または、一意のファイル名を作成する きちんとした小さなスニペット を再利用し、そのファイルへの完全パスをハッシュ呼び出しへの入力として使用することもできます。これにより、ファイルにマップできる一意の一定長の文字列が得られます。
Djangoは一意のファイル名を自動的に適用します。ファイルがすでに存在する場合、7つの一意の文字がファイル名に追加されます
Django 2.2でテスト済み