Comments 7
{{ form.hidden_tag() }}
{% for field in form if field.widget.input_type != 'hidden' %}
{{ field.label }}
{{ field }}
{% endfor %}
form.hidden_tag()
— метода фласка, отдает все хидден филды в невидимом диве. Чтобы было красиво, без этого input_type != 'hidden'
, можно добавить метод в саму форму (и наследовать ее), что-то вроде:from flask.ext.wtf.form import _is_hidden
class BaseForm(Form):
def visible_fields(self):
return [f for f in self if not _is_hidden(f)]
Ну и дальше в шаблоне. А для крутых случаев есть макросы.
Некоторые поля могут принимать аргументы. В нашем случае, мы просим форму создать наше поле openid с шириной в 80 символов
Логика в шаблоне, как по мне. Прямо из доков.
class LoginForm(Form):
openid = TextField(u'Full Name', [validators.required(), validators.length(max=80)])
WTForms — клевые.
CSRF_ENABLED
превратился в WTF_CSRF_ENABLED
.Также не рекомендую использовать
flash
, если есть коткурирующие запросы, например, ajax. Тк flash
хранится в сессии, сессия по умолчанию хранится в куках, если пришло два запроса со старыми куками, то будет дублирование или пропадание flash
. В данном примере все просто конечно.в листинге app/views.py в начале статьи ошибка, пропущена точка перед forms
from .forms import LoginForm
from flask.ext.wtf import Form
to:
from flask_wtf import Form
С новыми версиями модулей необходимо сделать некоторые правки, чтобы работали примеры.
В файле forms.py вместо from flask.ext.wtf import Form использовать:
from flask_wtf import FlaskForm
...
class LoginForm(FlaskForm):
Иначе будет ошибка, если пытаться грузить flask.ext.wtf:
ModuleNotFoundError: No module named 'flask.ext'
Или другая ошибка с {{form.hidden_tag()}}, если использовать просто Form:
jinja2.exceptions.UndefinedError: 'app.forms.LoginForm object' has no attribute 'hidden_tag'
Вместо Required использовать DataRequired:
from wtforms.validators import DataRequired
...
openid = StringField('openid', validators = [DataRequired()])
Иначе будет ошибка:
ImportError: cannot import name 'Required' from 'wtforms.validators'
В файле __init.py__ импортировать CSRFProtect и скормить ему app:
from flask import Flask
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect()
app = Flask(__name__)
app.config.from_object('config')
csrf.init_app(app)
Иначе поле csrf_token не будет появляться в форме:
<input id="csrf_token" name="csrf_token" type="hidden" value="...">
Мега-Учебник Flask, Часть 3: Формы