django-импорт-экспорт пустых строк перед заголовком csv вызывает исключение при импорте

#python #django #django-import-export

#python #django #django-импорт-экспорт

Вопрос:

При импорте данных из csv я понял, что эта ошибка возникает, если первая строка не является заголовком

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
  

Это работает только в том случае, если первая строка является заголовком

 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
  

Это работает для всех строк, кроме первой строки, которая всегда должна содержать заголовок, а если нет, выдается ошибка.

Комментарии:

1. Я видел это. Почему бы просто не удалить пустые строки перед импортом (вручную)?

2. Потому что именно пользователь будет импортировать данные, и я просто хочу, чтобы Python автоматически позаботился об этом.

Ответ №1:

После нескольких часов отладки я нашел ImportMixin класс, который находится в import_export/admin.py

Класс содержит вызываемый метод 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-файле не будет пустой строки, что приведет к тому, что первая строка будет заголовком, и это решит проблему. Я надеюсь, что это будет полезно всем, кто сталкивается с такой же проблемой.

ОБНОВЛЕНИЕ : существует также простой способ сделать то же create_dataset самое, перезаписав import_export/formats/base_formats.py

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())