2011-12-27 9 views
4

私はDjangoのEメールフォームクラスをFileFieldで書いています。アップロードされたファイルのMIMEタイプをチェックしてそのタイプのファイルをチェックしたいと思います。その後、ファイルタイプをpdfs、word、およびopen officeのドキュメントに限定したいと考えています。Djangoフォームのクリーンメソッドでファイルタイプを確認するにはどのように魔法を使用しますか?

このためには、私のpython-魔法をインストールしているとのpython-魔法のための仕様ごとに、次のようにファイルの種類をチェックしたいと思います:

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

しかし、最近アップロードされたファイルは、私のサーバー上のアドレスを欠いています。私はまた、ファイルの内容を与えられたMIMEタイプをチェックする "from_file_content"に似たmimeオブジェクトのメソッドについても知らない。

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

答えて

4

スタンは、バッファとの良好なバリアントを説明しました。残念ながら、この方法の弱点はファイルをメモリに読み込むことです。別のオプションは、temporary stored fileを使用している:

import tempfile 
import os 

tmp_file_name = request.FILES['my_file_field'].name 
tmp_file_dir = tempfile.gettempdir() # usually /tmp on Unix 
tmp_file_path = os.path.join(tmp_file_dir, tmp_file_name) 

mime = magic.Magic(mime=True) 
file_mime_type = mime.from_file(tmp_file_path) 

# then check mime and raise ValidationError if required 
+0

ありがとう、cleaned_dataでこれを試してみると、Djangoは/tmp/filename.docファイルが定義されていないことに注意しています。なぜアイデアはありますか? – dangerChihuahua007

+0

途中でファイルがメモリに読み込まれます。そして、私は一時的なパスで直接演奏することを避けることを好みます。 – Stan

+0

@Chi曽は、サーバーがメモリ不足のためにクラッシュしたときに、あなたがこれまで問題に直面したビューやフォームのコード –

4

なぜ、あなたのビューのような無しようとして何か:

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

またはメモリとのよりよいする:

m.from_buffer(request.FILES['my_file_field'].chunks()) 

申し訳ありませんああ、ちょうどあなたがあなたのフォームの検証であることしたいことを見たが、ただし、フォームの属性cleaned_dataを使用して同じ操作を行う必要があります。

+0

この第二のコードが正しくありません。 'multiple_chunks()'はチャンクを返さない*ブール値を返す。ファイルがチャンクで分割されるのに十分な大きさであるかどうか。 https://docs.djangoproject.com/en/1.5/topics/http/file-uploads/#django.core.files.uploadedfile.UploadedFile.multiple_chunks – zopieux

+0

@Zopieux:固定、ありがとう。 – Stan

+1

'from_buffer'はイテレータではなく文字列バッファを要求します。反復子に 'len()'がないので、あなたの新しいコードはAttributeErrorで失敗します。最初のチャンクを手動で取ってしまうことを除いて、私はここで素晴らしいソリューションは見当たりません。 – zopieux

1
mime = magic.Magic(mime=True) 

attachment = request.FILES['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()) 
0

は、あなたがそのアップロードされたファイルの拡張子が一致してMIMEタイプを検証するdjango-safe-filefieldパッケージを使用することができます。

from safe_filefield.forms import SafeFileField 

class MyForm(forms.Form): 

    attachment = SafeFileField(
     allowed_extensions=('xls', 'xlsx', 'csv') 
    ) 
関連する問題