web-dev-qa-db-ja.com

django HttpResponse経由でファイルを返す-ファイルが正しく提供されない

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つあります。それは、サーバーと関係があります。

14
Thomas Kremmel

文字列が必要だと思う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を開いたままにして、応答が読み取られた後にガベージコレクターに処理させることができます。

10
Ben James

ファイルに、本番環境では問題ないが開発段階では問題がない非ASCII文字が含まれている可能性がありますか?

ファイルをバイナリとして読み取ってみてください。

fsock = open(file_path,"rb")
12
alves

Settings.pyのMIDDLEWARE_CLASSESから「Django.middleware.gzip.GZipMiddleware」を無効にしてみてください

私も同じ問題を抱えていました。ミドルウェアフォルダを見回した後、このミドルウェアは私にとって有罪のようで、それを削除することでうまくいきました。

1
Anonymous