我繼承下面的Django視圖代碼,使用由另一個web服務來服務的輸出數據的下載版本:「上關閉的文件I/O操作」
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
函數本身 - 寫入反對Django 1.0 - 升級到1.5後仍然正常工作。不幸的是,覆蓋這一觀點現在測試失敗:
def testDownload(self):
self.client.login(username='test', password='test')
real = 'abc' * 100
data = base64.encodestring(real)
response = self.client.post("/api/v1/download/", {'data': data, 'filename': 'out.jpg'})
self.assertEqual(real, response.content)
self.assertEqual(response['Content-Disposition'], 'attachment; filename=out.jpg')
和錯誤:
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
。如果有什麼事情,它不會影響非測試情況嗎?
非常困惑。幫助讚賞。
我不確定什麼'FileWrapper'是,但你應該能夠做到你想要的沒有它。嘗試'file_content = StringIO(data)'並將'file_content'傳遞給'HttpResponse'然後重新運行你的測試。 – abstractpaper
感謝您的評論!它是'django.core.servers.basehttp.FileWrapper',僅供參考。例如參考[這個片段](http://djangosnippets.org/snippets/365/),我認爲這就是我的前任使用它的原因。 – supervacuo