6

FileField を使用して、Django で電子メール フォーム クラスを作成しました。MIME タイプをチェックして、アップロードされたファイルのタイプをチェックしたい。その後、ファイルの種類を pdf、word、およびオープン オフィス ドキュメントに制限したいと考えています。

この目的のために、python-magic をインストールしました。python-magic の仕様に従って、次のようにファイルの種類を確認したいと思います。

mime = magic.Magic(mime=True)
file_mime_type = mime.from_file('address/of/file.txt')

ただし、最近アップロードされたファイルには、サーバー上のアドレスがありません。また、ファイルのコンテンツを指定して MIME タイプをチェックする「from_file_content」に似た MIME オブジェクトのメソッドも知りません。

Djangoフォームでアップロードされたファイルのファイルタイプを検証するためにマジックを使用する効果的な方法は何ですか?

4

5 に答える 5

5
mime = magic.Magic(mime=True)

attachment = form.cleaned_data['attachment']

if hasattr(attachment, 'temporary_file_path'):
    # file is temporary on the disk, so we can get full path of it.
    mime_type = mime.from_file(attachment.temporary_file_path())
else:
    # file is on the memory
    mime_type = mime.from_buffer(attachment.read())

seek(0)また、次のことをしたいかもしれませんread()

if hasattr(f, 'seek') and callable(f.seek):
    f.seek(0)

Django コードの例。検証中に画像フィールドに対して実行されます。

于 2014-10-17T06:45:56.143 に答える
5

Stan は、バッファーを使用した優れたバリアントについて説明しました。残念ながら、この方法の弱点はファイルをメモリに読み込むことです。別のオプションは、一時的に保存されたファイルを使用することです:

import tempfile
import magic
with tempfile.NamedTemporaryFile() as tmp:
    for chunk in form.cleaned_data['file'].chunks():
        tmp.write(chunk)
    print(magic.from_file(tmp.name, mime=True))

また、ファイル サイズを確認することもできます。

if form.cleaned_data['file'].size < ...:
    print(magic.from_buffer(form.cleaned_data['file'].read()))
else:
    # store to disk (the code above)

さらに

名前付きの一時ファイルがまだ開いている間に、その名前を使用してファイルをもう一度開くことができるかどうかは、プラットフォームによって異なります (Unix では使用できますが、Windows NT 以降では使用できません)。

したがって、次のように処理したい場合があります。

import os
tmp = tempfile.NamedTemporaryFile(delete=False)
try:
    for chunk in form.cleaned_data['file'].chunks():
        tmp.write(chunk)
    print(magic.from_file(tmp.name, mime=True))
finally:
    os.unlink(tmp.name)
    tmp.close()

seek(0)また、次のことをしたいかもしれませんread()

if hasattr(f, 'seek') and callable(f.seek):
    f.seek(0)

アップロードされたデータの保存場所

于 2011-12-27T21:17:39.993 に答える
5

あなたの見解でそのようなことを試してみませんか:

m = magic.Magic()
m.from_buffer(request.FILES['my_file_field'].read())

または、実際にはオプションではない場合request.FILESの代わりに使用します。form.cleaned_datadjango.forms.Form

于 2011-12-27T19:46:02.990 に答える