问题详情:
在编译时可以通过测试的文件生成函数(使用bytes io作为文件载体,直接生成FileResponse对象返回),在使用uwsgi进行服务时报错,报错信息如下:
io.UnsupportedOperation: fileno
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 148, in __call__
response = environ['wsgi.file_wrapper'](response.file_to_stream, response.block_size)
SystemError: <built-in function uwsgi_sendfile> returned a result with an error set
原因分析:
报错反馈是无法获取文件描述符,经过测试,BytesIO 对象 确实不存在 fileno 方法,因此无法通过,在网上检索到相关解决方案为,使用 FileWrapper
参见链接:
解决方案
# 引用
from django.http import FileResponse
from wsgiref.util import FileWrapper
from urllib.parse import quote
# 使用FileWrapper后,导致FileResponse退化为StreamingHttpResponse,需要手动设置返回头信息
res = FileResponse(FileWrapper(file), filename=file_name, as_attachment=True)
# 设置返回头信息(参见FileResponse的set_headers方法)
res["Content-Type"] = 'application/pdf'
try:
file_name.encode('ascii')
file_expr = 'filename="{}"'.format(file_name)
except UnicodeEncodeError:
file_expr = "filename*=utf-8''{}".format(quote(file_name))
res['Content-Disposition'] = 'attachment; {}'.format(file_expr)
# 返回文件响应对象
res