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

发布于 2024-08-27 03:32:00 字数 1155 浏览 8 评论 0原文

我想在 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 类型,则可能会出现此问题。但他不确定这是否是问题所在。但有一件事是肯定的..它与服务器有关。

I want to return some files in a HttpResponse and I'm using the following function. The file that is returned always has a filesize of 1kb and I do not know why. I can open the file, but it seems that it is not served correctly. Thus I wanted to know how one can return files with django/python over a HttpResponse.

@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

Edit:
The bug is actually not a bug ;-)

This solution is working in production on an apache server, thus the source is ok.

While writing this question I tested it local with the django development server and was wondering why it does not work. A friend of mine told me that this issue could arise if the mime types are not set in the server. But he was not sure if this is the problem. But one thing for sure.. it has something to do with the server.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

陈甜 2024-09-03 03:32:00

是否该文件包含一些非 ASCII 字符,这些字符在生产中可以正常显示,但在开发中却不能?

尝试以二进制形式读取文件:

fsock = open(file_path,"rb")

Could it be that the file contains some non-ascii characters that render ok in production but not in development?

Try reading the file as binary:

fsock = open(file_path,"rb")
久隐师 2024-09-03 03:32:00

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

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

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

另外,我不确定您是否想在返回 response 之前对文件调用 close。在 shell 中尝试过这个(我没有在实际的 Django 视图中尝试过),似乎 response 直到 response 才访问该文件本身已被读取。尝试读取使用现已关闭的文件创建的 HttpResponse 会导致 ValueError:已关闭文件上的 I/O 操作

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

Try passing the fsock iterator as a parameter to HttpResponse(), rather than to its write() method which I think expects a string.

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

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

Also, I'm not sure you want to call close on your file before returning response. Having played around with this in the shell (I've not tried this in an actual Django view), it seems that the response doesn't access the file until the response itself is read. Trying to read a HttpResponse created using a file that is now closed results in a ValueError: I/O operation on closed file.

So, you might want to leave fsock open, and let the garbage collector deal with it after the response is read.

帅气称霸 2024-09-03 03:32:00

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

我遇到了同样的问题,在我查看了中间件文件夹后,这个中间件对我来说似乎有罪,删除它对我来说是成功的。

Try disabling "django.middleware.gzip.GZipMiddleware" from your MIDDLEWARE_CLASSES in settings.py

I had the same problem, and after I looked around the middleware folder, this middleware seemed guilty to me and removing it did the trick for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文