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
编辑: 这个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是否该文件包含一些非 ASCII 字符,这些字符在生产中可以正常显示,但在开发中却不能?
尝试以二进制形式读取文件:
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
迭代器作为参数传递给HttpResponse()
,而不是传递给我认为需要字符串的write()
方法。请参阅 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 toHttpResponse()
, rather than to itswrite()
method which I think expects a string.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 returningresponse
. Having played around with this in the shell (I've not tried this in an actual Django view), it seems that theresponse
doesn't access the file until theresponse
itself is read. Trying to read aHttpResponse
created using a file that is now closed results in aValueError: 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.尝试从 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.