django-import-export csv 前的空行 header 导入时触发异常
django-import-export empty rows before csv header trigger exception while importing
从 csv 导入数据时,我意识到如果第一行不是 header
,就会触发此错误
list indices must be integers or slices, not str
first_name,last_name,email,password,role
Noak,Larrett,nlarrett0@ezinearticles.com,8sh15apPjI,Student
Duffie,Milesap,dmilesap1@wikipedia.org,bKNIlIWVfNw,Student
仅当第一行是 header
时才有效
first_name,last_name,email,password,role
Noak,Larrett,nlarrett0@ezinearticles.com,8sh15apPjI,Student
Duffie,Milesap,dmilesap1@wikipedia.org,bKNIlIWVfNw,Student
...
我尝试覆盖 before_import
以删除任何空白行
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
indexes = []
for i in range(0, len(dataset)):
row = ''.join(dataset[i])
if row.strip() == '':
indexes.append(i)
for index in sorted(indexes, reverse=True):
del dataset[index]
return dataset
这适用于所有行,除了第一行应该始终包含 header,否则将抛出错误。
经过几个小时的调试,我找到了 ImportMixin
class,它位于 import_export/admin.py
class 包含一个名为 import_action
的方法,看起来像这样
def import_action(self, request, *args, **kwargs):
...
import_file = form.cleaned_data['import_file']
...
data = tmp_storage.read(input_format.get_read_mode())
...
dataset = input_format.create_dataset(data)
...
如您所见,这是在将上传文件传递给 input_format.create_dataset()
之前将其读取为字符串的函数。所以我所要做的就是添加一个自定义函数来删除空行
data = self.remove_blanks(data)
dataset = input_format.create_dataset(data)
import_export/admin.py/ImportMixin
def remove_blanks(self, data):
return os.linesep.join([s for s in data.splitlines() if s.strip()])
这样任何 csv 文件都不会有任何空行,这将强制第一行成为 header 并解决问题。我希望这对面临同样问题的任何人都有用。
UPDATE :还有一种简单的方法可以通过在 import_export/formats/base_formats.py
中覆盖 create_dataset
来实现相同的目的
import_export/formats/base_formats.py/TablibFormat
def create_dataset(self, in_stream, **kwargs):
in_stream = os.linesep.join([s for s in in_stream.splitlines() if s.strip()])
try:
return tablib.import_set(in_stream, format=self.get_title())
except:
return tablib.import_set('', format=self.get_title())
从 csv 导入数据时,我意识到如果第一行不是 header
,就会触发此错误list indices must be integers or slices, not str
first_name,last_name,email,password,role
Noak,Larrett,nlarrett0@ezinearticles.com,8sh15apPjI,Student
Duffie,Milesap,dmilesap1@wikipedia.org,bKNIlIWVfNw,Student
仅当第一行是 header
时才有效first_name,last_name,email,password,role
Noak,Larrett,nlarrett0@ezinearticles.com,8sh15apPjI,Student
Duffie,Milesap,dmilesap1@wikipedia.org,bKNIlIWVfNw,Student
...
我尝试覆盖 before_import
以删除任何空白行
def before_import(self, dataset, using_transactions, dry_run, **kwargs):
indexes = []
for i in range(0, len(dataset)):
row = ''.join(dataset[i])
if row.strip() == '':
indexes.append(i)
for index in sorted(indexes, reverse=True):
del dataset[index]
return dataset
这适用于所有行,除了第一行应该始终包含 header,否则将抛出错误。
经过几个小时的调试,我找到了 ImportMixin
class,它位于 import_export/admin.py
class 包含一个名为 import_action
的方法,看起来像这样
def import_action(self, request, *args, **kwargs):
...
import_file = form.cleaned_data['import_file']
...
data = tmp_storage.read(input_format.get_read_mode())
...
dataset = input_format.create_dataset(data)
...
如您所见,这是在将上传文件传递给 input_format.create_dataset()
之前将其读取为字符串的函数。所以我所要做的就是添加一个自定义函数来删除空行
data = self.remove_blanks(data)
dataset = input_format.create_dataset(data)
import_export/admin.py/ImportMixin
def remove_blanks(self, data):
return os.linesep.join([s for s in data.splitlines() if s.strip()])
这样任何 csv 文件都不会有任何空行,这将强制第一行成为 header 并解决问题。我希望这对面临同样问题的任何人都有用。
UPDATE :还有一种简单的方法可以通过在 import_export/formats/base_formats.py
create_dataset
来实现相同的目的
import_export/formats/base_formats.py/TablibFormat
def create_dataset(self, in_stream, **kwargs):
in_stream = os.linesep.join([s for s in in_stream.splitlines() if s.strip()])
try:
return tablib.import_set(in_stream, format=self.get_title())
except:
return tablib.import_set('', format=self.get_title())