我正在使用Django模块django-chunked-upload来接收可能较大的CSV文件。我可以假定CSV格式正确,但是我不能假定分隔符是什么。
上传完成后,将返回UploadedFile对象。我需要验证上传的CSV文件中是否包含正确的列,以及每一列中的数据类型是否正确。
使用csv.reader()
加载文件不起作用:
reader = csv.reader(uploaded_file)
next(reader)
>>> _csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
这可能是因为uploaded_file.content_type
和uploaded_file.charset
都以None
的身份出现。
我想出了一个相当雅致的解决方案来获取标题并遍历行:
i = 0
header = ""
for line in uploaded_file:
if i == 0:
header = line.decode('utf-8')
header_list = list(csv.reader(StringIO(header)))
print(header_list[0])
#validate column names
else:
tiny_csv = StringIO(header + line.decode('utf-8'))
reader = csv.DictReader(tiny_csv)
print(next(reader))
#validate column types
我还考虑过尝试加载实际保存文件的路径:
path = #figure out the path of the temp file
f = open(path,"r")
reader = csv.reader(f)
但是我无法从UploadedFile对象获取临时文件路径。
理想情况下,我想从UploadedFile对象中创建一个普通的读取器或DictReader,但这似乎使我望而却步。有人有想法么? -谢谢
答案 0 :(得分:0)
答案在chunked_upload / models.py中,该行具有以下行:
def get_uploaded_file(self):
self.file.close()
self.file.open(mode='rb') # mode = read+binary
return UploadedFile(file=self.file, name=self.filename,
size=self.offset)
因此,当您创建文件模型时,可以选择使用mode='r'
打开文件:
#myapp/models.py
from django.db import models
from chunked_upload.models import ChunkedUpload
from django.core.files.uploadedfile import UploadedFile
class FileUpload(ChunkedUpload):
def get_uploaded_file(self):
self.file.close()
self.file.open(mode='r') # mode = read+binary
return UploadedFile(file=self.file, name=self.filename,
size=self.offset)
这使您可以获取返回的UploadedFile实例并将其解析为csv:
def on_completion(self, uploaded_file, request):
reader = csv.reader(uploaded_file)
...