Flask在第一次验证时不知道动态添加的输入字段

问题描述

如果用户单击,我将通过按钮动态添加新的文件上传字段。 验证仅在第二次尝试中通过,这是因为flask / wtforms不知道新动态创建的输入字段。每当我单击“提交”按钮时,它只会在第一个字段中警告文件丢失。

一旦我放入所有必需的文件并提交,第一次尝试就会失败,但是之后,字段列表已被初始化为所需的大小,并且下次我提交相同数量文件时,它将起作用。

forms.py

class ChildForm(FlaskForm):
    class Meta:
        csrf = False

    childvalue1= IntegerField(default=1,validators=[Datarequired()])
    childvalue2= FileField(validators=[Filerequired(),FileAllowed(['mp3'])])


class ParentForm(FlaskForm):
    parentvalue1= FileField('PDF File',validators=[Filerequired(),FileAllowed(['pdf'])])
    parentfieldlist= FieldList(FormField(ChildForm),min_entries=1)
    submit = SubmitField('Upload')

html文件

<form action="" method="post" enctype="multipart/form-data">
        {{ form.hidden_tag() }}

        <!-- PDF Upload -->
        <div>
            <label class="label">{{ form.parentvalue1.label }}</label>
            {{ form.parentvalue1}}
            <br>
        </div>

        <!-- Audio Upload -->
        <br>
        <div>
            <label class="label">{{ form.parentfieldlist.label }}</label>
            <table id="audiotable">
                {% for entry in form.parentfieldlist%}
                <tr>
                    {% for subfield in entry %}
                    <td>{{ subfield }}</td>
                    {% endfor %}
                </tr>
                {% endfor %}
            </table>
        </div>

        <br>
        <button type='button' class="add_more">Add More Files</button>
        <br><br>
        <p> {{ form.submit(class='button is-link') }}

    </form>

JS创建更多输入字段

<script>

    String.format = function () {
        var s = arguments[0];
        for (var i = 0; i < arguments.length - 1; i++) {
            var reg = new RegExp("\\{" + i + "\\}","gm");
            s = s.replace(reg,arguments[i + 1]);
        }
        return s;
    }

    var fieldNum = 1;
    $('.add_more').click(function (e) {
        e.preventDefault()
        var firstTag = "parentfieldlist-" + fieldNum + "-childvalue1"
        var secondTag = "parentfieldlist-" + fieldNum + "-childvalue2"
        var rowTemplate = `<tr><td><input type='text' id=${firstTag } name=${firstTag } value=${fieldNum + 1} /></td>
            <td><input type='file' id=${secondTag } name=${secondTag }/></td></tr>`;
        $("#audiotable").append(rowTemplate);
        fieldNum++;
    });
    
</script>

任何人碰巧都知道如何使它工作? 另一个例子。如果我添加第二个上传字段并提交,这就是我的函数打印的内容

[{'childvalue1': 1,'childvalue2': <FileStorage: 'somefile.mp3' ('audio/mpeg')>},{'childvalue1': 2,'childvalue2': None}]

如果我再做一次并提交,它将起作用。 在使用append_entry()的情况下,有一些带有ajax调用python函数的hacky解决方案,但是我不相信这些,也不确定它们是否真的可以解决问题。本质上,文件在首次提交时始终为空

编辑:如果我从childvalue 2中删除“ Filerequired”,则根本无法使用。这是一张图片显示我的意思

enter image description here

该表单不知道我通过“按”按钮添加的第二个上传字段 谢谢你的建议

解决方法

答案非常简单,但对我而言并不那么明显。

<input type='file' id=${secondTag } name=${secondTag }/>

需要像这样,就像我输入的第一个childvalue一样,因为它具有默认值

<input type='file' id=${secondTag } name=${secondTag } value=""/>

现在Flask可以在提交/验证时识别动态添加的文件。从一开始就应该很明显,因为第一个值始终被传输,但是第二个值是“ none”,唯一的区别是两者之间的“值”