Flask не знает о динамически добавляемых полях ввода при первой проверке

#python #flask #flask-wtforms #wtforms

#python #flask #flask-wtforms #wtforms

Вопрос:

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

Если я сделаю это снова и отправлю, это сработает.
Есть несколько хакерских решений с ajax-вызовами функций python, где вы используете append_entry (), но я не уверен в них и не уверен, действительно ли они решают проблему. По сути, файл всегда отсутствует при первой отправке

Редактировать: Если я удалю ‘FileRequired’ из дочернего значения 2, это вообще не сработает. Вот рисунок, чтобы показать, что я имею в виду

введите описание изображения здесь

Форме не известно о втором поле загрузки, которое я добавил с помощью кнопки by Спасибо за любые предложения

Ответ №1:

Ответ был ОЧЕНЬ простым, но для меня не настолько очевидным.

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

должно быть таким, как первое дочернее значение, которое я ввел, поскольку оно имеет значение по умолчанию

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

Теперь Flask распознает динамически добавляемые файлы при отправке / проверке. Это должно было быть очевидно с самого начала, поскольку первое значение всегда передавалось, но второе значение было «none» с единственной разницей в «value» между ними