django + uwsgi 问题解决 io.UnsupportedOperation: fileno

问题详情:
在编译时可以通过测试的文件生成函数(使用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

参见链接:

https://stackoverflow.com/questions/61834988/django-systemerror-built-in-function-uwsgi-sendfile-returned-a-result-with-a

解决方案

# 引用
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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值