django通过HttpResponse返回文件 - 文件未正确提供

时间:2010-03-29 13:52:32

标签: django filestream

我想在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

编辑: 这个bug实际上不是一个bug; - )

此解决方案正在apache服务器上进行生产,因此源可以。

在写这个问题的时候,我用django开发服务器在本地测试了它,并想知道为什么它不起作用。我的一个朋友告诉我,如果服务器中没有设置mime类型,可能会出现此问题。但他不确定这是不是问题。但有一点可以肯定......它与服务器有关。

3 个答案:

答案 0 :(得分:12)

该文件是否包含一些非ascii字符,这些字符在生产中呈现正常但不在开发中?

尝试将文件读取为二进制文件:

fsock = open(file_path,"rb")

答案 1 :(得分:10)

尝试将fsock迭代器作为参数传递给HttpResponse(),而不是传递给我认为需要字符串的write()方法。

response = HttpResponse(fsock, mimetype=...)

请参阅http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators

此外,我不确定您要在回复close之前在您的文件上调用response。在shell中玩过这个(我没有在实际的Django视图中尝试过这个),似乎response在读取response本身之前不会访问该文件。尝试阅读使用现已关闭的文件创建的HttpResponse会产生ValueError: I/O operation on closed file

因此,您可能希望保持fsock处于打开状态,并在读取响应后让垃圾收集器处理它。

答案 2 :(得分:1)

尝试从settings.py中的MIDDLEWARE_CLASSES中禁用“django.middleware.gzip.GZipMiddleware”

我遇到了同样的问题,在浏览了中间件文件夹后,这个中间件对我来说似乎很内疚,删除它对我来说很有用。