我想在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类型,可能会出现此问题。但他不确定这是不是问题。但有一点可以肯定......它与服务器有关。
答案 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”
我遇到了同样的问题,在浏览了中间件文件夹后,这个中间件对我来说似乎很内疚,删除它对我来说很有用。