我有这样的表格:
class CSVImportForm(AuthorshipMixin, FormMixin, forms.Form):
data = forms.FileField()
def import_csv(self):
school_csv = csv.DictReader(self.cleaned_data['data'])
for row in school_csv:
print(row)
import_csv()
的目的是将CSV导入应用程序的数据库,但为了简洁起见,它已被修改。
当我尝试迭代school_csv
时发生异常,我猜是DictReader
首次尝试读取文件时:
Traceback:
File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.5/dist-packages/django/views/generic/base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/django/views/generic/base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/django/views/generic/edit.py" in post
215. return self.form_valid(form)
File "/opt/project/project/import/views.py" in form_valid
16. form.import_csv()
File "/opt/project/project/import/forms.py" in import_csv
67. for row in school_csv:
File "/usr/lib/python3.5/csv.py" in __next__
109. self.fieldnames
File "/usr/lib/python3.5/csv.py" in fieldnames
96. self._fieldnames = next(self.reader)
Exception Type: Error at /import/
Exception Value: iterator should return strings, not bytes (did you open the file in text mode?)
我不相信我有机会选择打开文件的模式。我怎么能在文本模式下打开所以csv模块会处理它?</ p>
我注意到InMemoryUploadedFile
有一个file
属性似乎很有用,但它是一个io.BytesIO
对象。我想我可以做一些涉及手动指定encoding.etc的魔法,但我想这会让Django变得更容易。
最好的方法是什么?
答案 0 :(得分:4)
尝试使用
as_string = self.cleaned_data['data'].read().decode("utf-8")
school_csv = csv.DictReader(as_string)
如果需要str
或
from io import StringIO
school_csv = csv.DictReader(StringIO(as_string))
如果它想要StringIO。
答案 1 :(得分:2)
还有一个流媒体变体:
reader = csv.DictReader(io.TextIOWrapper(request.FILE["csv"]))
它应该可以更好地处理大量内容。