Комментарий @ADyson объясняет вашу конкретную проблему, которая заключается в том, что вы действительно должны изменить код на:
$.ajax({
data : {
"keyword-1" : $('#keyword-1').val(),
"keyword-2" : $('#keyword-2').val(),
"keyword-3" : $('#keyword-3').val()
},
Но это не решит вашу основную проблему.Вы используете WTForms, по-видимому, потому что вы хотите использовать встроенную библиотеку проверки формы на стороне сервера.В данный момент ваш класс Form
не выполняет проверку, поэтому строка form.validate_on_submit()
ничего не сделает.Вставьте следующее:
from wtforms.validators import InputRequired
...
given_name = StringField(validators=[InputRequired()])
По крайней мере, теперь вы можете проверить свой код, чтобы он попытался выполнить некоторую базовую службу проверки.
Но здесь есть другая проблема.Ваш Form
класс ожидает обработки двух полей формы;given_name
и family_name
, но данные, которые вы POST
через AJAX не содержат ни в одном из этих двух полей, на самом деле данные, которые вы публикуете, указаны как:
data : {
"keyword-1" : $('#keyword-1').val(),
"keyword-2" : $('#keyword-2').val(),
"keyword-3" : $('#keyword-3').val()
},
И это -вы не отправляете автоматически другие поля формы в своем HTML-коде, поскольку вы прямо и явно указали здесь данные.
На своем уровне core
маршруты Flask получают объект с именем request
.Если вы вставите строку
def new():
print("the data supplied in post request form is: ", request.form)
, тогда вы сможете отлаживать то, что видите в переданных данных.В этом запросе произойдет следующее: form.validate_on_submit()
завершится с ошибкой {'given_name: ['This field is required.']}
.Даже если вы предоставите это поле в форме, произойдет ошибка, потому что вы не передаете его явно.Когда вы выполняете form = Form()
, form
заполняется данными из request
.
Исправив это, ваш код также будет страдать с KeyError
, потому что если некоторые поля являются необязательными, или пользователь недобавил второе или третье необязательное поле ввода, тогда:
keyword2 = request.form['keyword-2']
не будет существовать, поэтому вместо этого попробуйте что-то вроде
keyword2 = request.form.get('keyword-2', None)
, так как это, по крайней мере, имеет условие escape.
Я ценю, что вы не обязательно хотели использовать мой предложенный подход ранее с Webargs вместо WTForms, но в вашем примере включение WTForms абсолютно бесполезно (возможно, кроме HTML-рендеринга на стороне клиента).Когда вы получаете доступ к отправленным значениям, вы обращаетесь к ним напрямую в request.form
, что полностью обходит проверку на стороне сервера и делает form=Form()
полностью избыточной.
Простое решение
Если вы знаете, что выбудет искать не более 3 ключевых слов, после чего вы можете предварительно заполнить форму скрытыми полями:
class Form(FlaskForm):
given_name = StringField(validators=[InputRequired()], render_kw={'placeholder': 'Given Name'})
family_name = StringField(render_kw={'placeholder': 'Surname'})
keyword1 = StringField(validators=[Optional()], render_kw={'placeholder': 'k1'})
keyword2 = StringField(validators=[Optional()], render_kw={'style': 'display:none;', 'placeholder': 'k2'})
keyword3 = StringField(validators=[Optional()], render_kw={'style': 'display:none;', 'placeholder': 'k3'})
На вашем HTML-дисплее появятся следующие формы:
{{ form.given_name }}
{{ form.family_name }}
{{ form.keyword1 }}
{{ form.keyword2 }}
{{ form.keyword3 }}
Из-заrender_kw
будет виден только Keyword1, но вы можете легко написать код JS, чтобы нажать кнопку и изменить свойство отображения с none
для Keyword2 и Keyword3, аналогично тому, что вы делали выше, но в меньшей степени, так как требуется только getElementByIdи установите свойство style.
Когда вы нажмете submit
, вам не нужно перехватывать его и выполнять AJAX-запрос (то есть «form.js» может быть полностью удален), вы можете просто POST какобычная форма действий.WTForms проверит его в соответствии с вашим классом и заполнит данные как form.keyword2.data
и т. Д.