在Django视图tes中使用StringIO的“关闭文件的I/O操作”

2024-10-04 01:27:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我继承了以下Django视图代码,由另一个web服务用来提供输出数据的可下载版本:

def index(request):
    # ... (snip) ...
    data = base64.decodestring(request.POST['data'])
    filename = request.POST['filename']

    wrapper = FileWrapper(StringIO(data))

    response = HttpResponse(wrapper, content_type=guess_type(str(filename))[0])

    response['Content-Length'] = len(data)
    response['Content-Disposition'] = "attachment; filename=" + filename

    return response

这个函数本身是针对django1.0编写的,在升级到1.5之后仍然可以正常工作。不幸的是,涵盖这一观点的测试现在失败了:

^{pr2}$

错误是:

Traceback (most recent call last):
  File "/home/fred/.secret_projects/final/gerbils/tests/amf.py", line 548, in testDownload
    self.assertEqual(real, response.content)
  File "/home/fred/.virtualenvs/cunning_plot/lib/python2.7/site-packages/django/http/response.py", line 282, in content
    self._consume_content()
  File "/home/carl/.virtualenvs/cunning_plot/lib/python2.7/site-packages/django/http/response.py", line 278, in _consume_content
    self.content = b''.join(self.make_bytes(e) for e in self._container)
  File "/home/carl/.virtualenvs/cunning_plot/lib/python2.7/site-packages/django/http/response.py", line 278, in <genexpr>
    self.content = b''.join(self.make_bytes(e) for e in self._container)
  File "/usr/lib64/python2.7/wsgiref/util.py", line 30, in next
    data = self.filelike.read(self.blksize)
  File "/usr/lib64/python2.7/StringIO.py", line 127, in read
    _complain_ifclosed(self.closed)
  File "/usr/lib64/python2.7/StringIO.py", line 40, in _complain_ifclosed
    raise ValueError, "I/O operation on closed file"
ValueError: I/O operation on closed file

所以。。有什么想法吗?我在testDownload()index()中看不到任何在需要读取之前必须“关闭”StringIO的内容。如果真的有什么问题的话,它会不会也影响到非测试的情况呢?在

很困惑。感谢帮助。在


Tags: inpyselfhomedataplotresponserequest
1条回答
网友
1楼 · 发布于 2024-10-04 01:27:19

查看close在何处被调用的一种简单方法是只将StringIO子类化并在close函数中放置一个断点。在

class CustomStringIO(StringIO):
    def close(self):
        import pdb; pdb.set_trace()
        super(CustomStringIO, self).close()

这个的堆栈是

^{pr2}$

看起来测试客户机正在关闭响应,而响应又在FileWrapper上调用close,后者在StringIO上调用close。在您真正到达response.content之前,这些都已经完成了。在

你需要FileWrapper的原因吗?由于HttpResponse接受字符串内容,base64.decodestring返回一个二进制字符串,因此似乎可以直接将data传递给{},而不必创建StringIO和{}。在

相关问题 更多 >