在视图中,我创建一个使用一个简单的CSV作家CSV完全由Django的HttpResponse对象:如何阅读CSV Django的HTTP响应
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="foobar.csv"'
writer = csv.writer(response)
table_headers = ['Foo', 'Bar']
writer.writerow(table_headers)
bunch_of_rows = [['foo', 'bar'], ['foo2', 'bar2']]
for row in bunch_of_rows:
writer.writerow(row)
return response
在一个单元测试,我想测试某些方面这个csv,所以我需要阅读它。我想这样做,像这样:
response = views.myview(args)
reader = csv.reader(response.content)
headers = next(reader)
row_count = 1 + sum(1 for row in reader)
self.assertEqual(row_count, 3) # header + 1 row for each attempt
self.assertIn('Foo', headers)
但测试失败,在headers = next(reader)
行:
nose.proxy.Error: iterator should return strings, not int (did you open the file in text mode?)
我在的HttpResponse源看到response.content
咳串回来了作为一个字节字符串,但我不知道正确的方式来处理,让csv.reader
正确读取文件。我想我可以只用response
替换response.content
(因为你写的对象本身,而不是它的内容),但只是导致该错误的微小的变化:
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
这似乎更接近,但明显仍然错误。阅读csv
文档,我认为我无法正确打开文件。如何“打开”这个类似文件的对象,以便csv.reader
可以解析它?
虽然这两个答案都是有效的,但在我的具体情况下,内容非常小,以至于knbk的答案所提供的性能改进略微超出了该答案的可读性。这两个人都接受了。我最终使用的最终形式是:'reader = csv.reader(StringIO(response.content.decode('utf-8')))'。我选择只导入StringIO,因此省略'io.' – fildred13