HttpResponseでいくつかのファイルを返したいのですが、次の関数を使用しています。返されるファイルのファイルサイズは常に1kbで、理由はわかりません。ファイルを開くことはできますが、正しく提供されていないようです。したがって、HttpResponseを介してDjango/pythonでファイルを返す方法を知りたいと思いました。
@login_required
def serve_upload_files(request, file_url):
import os.path
import mimetypes
mimetypes.init()
try:
file_path = settings.UPLOAD_LOCATION + '/' + file_url
fsock = open(file_path,"r")
#file = fsock.read()
#fsock = open(file_path,"r").read()
file_name = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
print "file size is: " + str(file_size)
mime_type_guess = mimetypes.guess_type(file_name)
if mime_type_guess is not None:
response = HttpResponse(fsock, mimetype=mime_type_guess[0])
response['Content-Disposition'] = 'attachment; filename=' + file_name
except IOError:
response = HttpResponseNotFound()
return response
編集:バグは実際にはバグではありません;-)
このソリューションはApacheサーバー上で本番環境で機能しているため、ソースは問題ありません。
この質問を書いている間、私はそれをDjango開発サーバーでローカルにテストし、なぜそれが機能しないのか疑問に思いました。私の友人は、mimeタイプが設定されていない場合にこの問題が発生する可能性があると私に言いましたサーバー。しかし、これが問題であるかどうかはわかりませんでした。しかし、確かなことが1つあります。それは、サーバーと関係があります。
文字列が必要だと思うHttpResponse()
メソッドではなく、fsock
イテレータをパラメータとしてwrite()
に渡してみてください。
response = HttpResponse(fsock, mimetype=...)
http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators を参照してください。
また、close
を返す前に、ファイルでresponse
を呼び出したいかどうかもわかりません。シェルでこれを試してみましたが(実際のDjangoビューでは試していません)、response
自体が読み取られるまで、response
はファイルにアクセスしないようです。試してみる現在閉じられているファイルを使用して作成されたHttpResponse
を読み取ると、ValueError: I/O operation on closed file
になります。
したがって、fsock
を開いたままにして、応答が読み取られた後にガベージコレクターに処理させることができます。
ファイルに、本番環境では問題ないが開発段階では問題がない非ASCII文字が含まれている可能性がありますか?
ファイルをバイナリとして読み取ってみてください。
fsock = open(file_path,"rb")
Settings.pyのMIDDLEWARE_CLASSESから「Django.middleware.gzip.GZipMiddleware」を無効にしてみてください
私も同じ問題を抱えていました。ミドルウェアフォルダを見回した後、このミドルウェアは私にとって有罪のようで、それを削除することでうまくいきました。