Flask-WTF - validate_on_submit() никогда не выполняется
Я использую Flask-WTF:
Вот моя форма:
from flask.ext.wtf import Form, TextField
class BookNewForm(Form):
name = TextField('Name')
Вот контроллер:
@book.route('/book/new', methods=['GET', 'POST'])
def customers_new():
form = BookNewForm()
if form.is_submitted():
print "submitted"
if form.validate():
print "valid"
if form.validate_on_submit():
flash("Successfully created a new book")
return redirect(url_for('.books_show'))
return render_template('views/books_new.html', form=form)
Теперь проблема в том, что если вы посмотрите на мои операторы печати, она всегда печатает отправленные, но НИКОГДА не печатает, и validate_on_submit() никогда не выполняется. Почему?
Ответы
Ответ 1
Вы не вставляете поле CSRF в HTML-форму.
<form method=post>
{{ form.csrf_token }}
{{ form.name }}
<input type=submit>
</form>
После добавления form.csrf_token
в шаблон (docs) форма будет проверяться как ожидалось.
Добавьте print(form.errors)
после проверки формы, чтобы увидеть возникшие ошибки. errors
перед проверкой будет пустым. В этом случае возникает ошибка в отсутствии
@book.route('/book/new_no_csrf', methods=['GET', 'POST'])
def customers_new_no_csrf():
form = BookNewForm()
print(form.errors)
if form.is_submitted():
print "submitted"
if form.validate():
print "valid"
print(form.errors)
if form.validate_on_submit():
flash("Successfully created a new book")
return redirect(url_for('.books_show'))
return render_template('books_new.html', form=form)
{}
submitted
{'csrf_token': [u'CSRF token missing']}
127.0.0.1 - - [29/May/2012 02:01:08] "POST /book/new_no_csrf HTTP/1.1" 200 -
127.0.0.1 - - [29/May/2012 02:01:08] "GET /favicon.ico HTTP/1.1" 404 -
Я создал пример на GitHub.
Ответ 2
вы можете печатать ошибки
print form.errors
или
app.logger.debug(form.errors)
и если вы получили csrf-ошибку, вы должны установить form.csrf_token в свой шаблон.
Ответ 3
вставьте это после тега в файл шаблона html:
{{ form.csrf_token }}
Ответ 4
Я очищал сеанс фляжи, если я не был зарегистрирован перед каждым запросом. Это вызвало эту проблему.
@main.before_request
def before_request():
if not current_user.is_authenticated():
# TODO clean sessions may cause CSRF missing issue
session.clear()
print "Session Cleared"
return redirect(url_for('auth.login'))
Ответ 5
Я столкнулся с этим, пытаясь сделать FormField
итерацией по моему FieldList
в моем шаблоне. Мне пришлось встроить два элемента hidden_tag один для формы FieldList
и один для формы FieldForm
, искать комментарии к шаблону для ключевого слова "HIDDEN TAG"
class ParamRangeForm( FlaskForm ):
minX = FloatField( )
maxX = FloatField( )
class ParamRangesForm( FlaskForm ):
paramRanges = FieldList( FormField( ParamRangeForm ) )
submit = SubmitField( 'Submit' )
def loadParams( self ) :
for paramName in ["p1" , "p2" , "p3", "p4"] :
prf = ParamRangeForm( )
prf.minX = -100.9#float('-inf')
prf.maxX = 100.5#float('-inf')
self.paramRanges.append_entry( prf )
...
<form action="" method="POST" enctype="multipart/form-data">
{{ rangesForm.hidden_tag() }} <!--#### HIDDEN TAG #1 -->
<table>
<!--Print Column Headers-->
<thead>
<tr>
<th class="ColumnHeader">Parameter</td>
<th class="ColumnHeader">Min</td>
<th class="ColumnHeader">Max</td>
</tr>
</thead>
<!--Print Parameter Rows-->
<tbody>
{% for paramRange in rangesForm.paramRanges %}
<tr>
{{ paramRange.hidden_tag() }} <!--#### HIDDEN TAG #2 -->
<td>p{{ loop.index }}</td>
<td>{{ paramRange.minX }}</td>
<td>{{ paramRange.maxX }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{{ rangesForm.submit() }}
</form>