私の目標は、Django ModelForm の FileField を PDF と Word ドキュメントに制限することです。私がグーグルで検索した回答はすべて、別のファイルハンドラーの作成を扱っていますが、ModelForm のコンテキストでそれを行う方法がわかりません。アップロードするファイルの種類を制限するために使用できる settings.py の設定はありますか?
8 に答える
次のような検証メソッドを作成します。
def validate_file_extension(value):
if not value.name.endswith('.pdf'):
raise ValidationError(u'Error message')
次のように FileField バリデーターに含めます。
actual_file = models.FileField(upload_to='uploaded_files', validators=[validate_file_extension])
また、モデルが許可する拡張機能を手動で設定する代わりに、setting.py でリストを作成し、それを反復処理する必要があります。
編集
複数のファイルをフィルタリングするには:
def validate_file_extension(value):
import os
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.pdf','.doc','.docx']
if not ext in valid_extensions:
raise ValidationError(u'File not supported!')
ファイル名の拡張子による検証は、一貫した方法ではありません。たとえば、picture.jpg の名前を picture.pdf に変更しても、検証でエラーは発生しません。
より良いアプローチは、ファイルの content_type をチェックすることです。
検証方法
def validate_file_extension(value):
if value.file.content_type != 'application/pdf':
raise ValidationError(u'Error message')
使用法
actual_file = models.FileField(upload_to='uploaded_files', validators=[validate_file_extension])
より一般的に使用するために、ExtensionValidator
Django の組み込みの を拡張する小さなクラスを作成しましたRegexValidator
。1 つまたは複数の拡張機能と、オプションのカスタム エラー メッセージを受け入れます。
class ExtensionValidator(RegexValidator):
def __init__(self, extensions, message=None):
if not hasattr(extensions, '__iter__'):
extensions = [extensions]
regex = '\.(%s)$' % '|'.join(extensions)
if message is None:
message = 'File type not supported. Accepted types are: %s.' % ', '.join(extensions)
super(ExtensionValidator, self).__init__(regex, message)
def __call__(self, value):
super(ExtensionValidator, self).__call__(value.name)
フィールドとインラインでバリデーターを定義できるようになりました。
my_file = models.FileField('My file', validators=[ExtensionValidator(['pdf', 'doc', 'docx'])])
私はこれらの行に沿って何かを使用します(これには「pip install filemagic」が必要であることに注意してください...):
import magic
def validate_mime_type(value):
supported_types=['application/pdf',]
with magic.Magic(flags=magic.MAGIC_MIME_TYPE) as m:
mime_type=m.id_buffer(value.file.read(1024))
value.file.seek(0)
if mime_type not in supported_types:
raise ValidationError(u'Unsupported file type.')
おそらく、前の例をこれに組み込むこともできます。たとえば、拡張機能/アップロードされたタイプもチェックします (魔法よりも一次チェックの方が速いかもしれません)。ブラウザが提供するヘッダーではなく、ファイル内。
注: これは、FileField モデルのバリデーターのリストに追加したいバリデーター関数です。
ModelFormでclean_[your_field]メソッドを使用してこれを処理します。クリーンなメソッドでチェックするためにsettings.pyで受け入れ可能なファイル拡張子のリストを設定できますが、アップロードの種類を制限するための組み込みのsettings.pyはありません。
たとえば、Django-Filebrowserは、settings.pyに受け入れ可能なファイル拡張子のリストを作成するアプローチを採用しています。
それがあなたを助けることを願っています。