【问题标题】:Django : Manipulating a form's csv file inputDjango:操作表单的 csv 文件输入
【发布时间】:2020-06-26 18:41:57
【问题描述】:

问题:- 我在自定义函数中得到一个空的 rowsheader。找不到原因。

问题的背景:- 我正在处理一个 django 页面/表单,该页面/表单应该采用提交的 csv 文件,如果选中了表单中的 'type' 字段,它将检查提供的 csv 是否具有一组特定的列。

注意,下面的所有类都在一个模块中(validations.py)。我输入的csv文件也是正确的,有行和标题。

以下只是我遇到问题的任务的一部分..(并且没有依赖关系,至少对于问题而言)。

class ReportTypeValidator:
    def __init__(self, config_form, brand_form_set):
        self.config_form = config_form
        self.brand_form_set = brand_form_set

    def check(self):
        is_checked = self.config_form.cleaned_data['type']
        if is_checked:
            self.REVIEW_FILE_COLUMNS_TYPE = REVIEW_FILE_COLUMNS+['Report_Type']
            files = self._get_brand_files(self.brand_form_set)
            print('%%%%%%%%%%%%%')
            print(files)
            for file in files:
                rows, header = FieldFileCsvHelper().read_csv_file(file)
                print('==========')
                print(rows)
                print(header)
                print(file)
                missing_columns = get_missing_columns(header, self.REVIEW_FILE_COLUMNS_TYPE)

                if missing_columns:
                    message = self.message.format(missing_columns=', '.join(missing_columns))
                    raise ValidationError(
                        message,
                        code=self.code,)

        else:
            pass

    def _get_brand_files(self, brand_form_set):
        file_list = []
        for index, brand_form in enumerate(brand_form_set):
            file =brand_form.files[f'form-{index}-review_file']
            file_list.append(file)
            print('@@@@@@@@@@@@@')            
            print(file_list)
        return file_list


在我展示更多细节之前,请在上述函数执行期间查看 django 终端。我添加了打印语句来查看文件。问题是我得到一个空行和标题。

django_1        |  @@@@@@@@@@@@@
django_1        | [<InMemoryUploadedFile: 500_reviews_withoutType.csv (text/csv)>]
django_1        |  %%%%%%%%%%%%%
django_1        | [<InMemoryUploadedFile: 500_reviews_withoutType.csv (text/csv)>]
django_1        |  ==========
django_1        | []
django_1        | None
django_1        | 500_reviews_withoutType.csv

FieldFileCsvHelper 类:-

class FieldFileCsvHelper:
    def read_csv_file(self, field_file: FieldFile):
        dict_reader = self._get_dict_reader(field_file)
        rows = list(dict_reader)
        header = self._get_csv_header(dict_reader)
        return rows, header

下面的函数(这是正确的)是生成错误的函数,因为我们在调用它时传递了一个空的标头参数。

def get_missing_columns(header: List[str], mandatory_columns: List[str]) -> List[str]:
    missing_columns = []
    for column in mandatory_columns:
        if column not in header:
            missing_columns.append(column)
    return missing_columns

错误(由于标题为空):

django_1        |   File "/app/app1/validators.py", line 83, in check
django_1        |     missing_columns = get_missing_columns(header, self.REVIEW_FILE_COLUMNS_TYPE)
django_1        |   File "/app/app1/validators.py", line 150, in get_missing_columns
django_1        |     if column not in header:
django_1        | TypeError: argument of type 'NoneType' is not iterable

我在正确获取header 时错过了什么?

如果我需要添加更多详细信息,请告诉我。

【问题讨论】:

  • FieldFileCsvHelper().read_csv_file 没有返回您期望的结果。可以加这个方法吗
  • @IainShelvington 我已经添加了这个方法

标签: python django forms csv


【解决方案1】:

终于找到原因了。没有返回 header 的原因是由于 cursor/iterable 在 FieldFile 的末尾。

例如,如果 FieldFile 之前被任何其他函数读取过,那么要再次通过它,请确保您设置了 field_file.seek(0)。就我而言,我将它添加到 FieldFileCsvHelper 函数中,并且它起作用了。 header 值现在正在从 csv 中提取。

class FieldFileCsvHelper:
    def read_csv_file(self, field_file: FieldFile):
        field_file.seek(0)                             # Added this line
        dict_reader = self._get_dict_reader(field_file)
        rows = list(dict_reader)
        header = self._get_csv_header(dict_reader)
        return rows, header


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2012-02-09
    • 1970-01-01
    相关资源
    最近更新 更多