Выпуск
WTForms не поддерживает определение полей в атрибуте словаря уровня класса. Базовый класс Form использует FormMeta (из того же файла) в качестве метакласса для идентификации несвязанных полей WTForm в определении класса и связывания их с текущей формой, и это только обнаруживает атрибуты уровня класса.
Решение
Ниже приведен минимальный рабочий пример использования функции фабрики форм.
Дополнительные поля формы передаются в виде лямбда-функции через параметр field_factory
, так что мы можем отложить создание дополнительных полей до тех пор, пока не будет создано поле name
(хотя любой вызываемый, который возвращает dict, будет работать ). Это необходимо, поскольку WTForms сортирует поля по порядку создания, а не по порядку, указанному в поле items
внутри функции make_form()
.
Затем вы можете отобразить их, выполнив итерацию по форме вместо указания ручного порядка.
Проверено на python 3.7.1.
from flask import Flask
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.config['SECRET_KEY'] = "secret"
def make_form(field_factory, name="MyForm"):
items = dict(name=StringField('New Name', validators=[DataRequired()]),
**field_factory())
my_form = type(name, (FlaskForm,), items)
return my_form
if __name__ == "__main__":
with app.test_request_context("/"):
my_form = make_form(field_factory=lambda: dict(
Field1=StringField('Field 1', validators=[DataRequired()]),
Field2=StringField('Field 2', validators=[DataRequired()])
))
form = my_form()
for field in form:
print(field())
выход
<input id="name" name="name" required type="text" value="">
<input id="Field1" name="Field1" required type="text" value="">
<input id="Field2" name="Field2" required type="text" value="">
<input id="csrf_token" name="csrf_token" type="hidden" value="IjY5ZWMyNWYxYzg3MzU2MTM1MGMyMTI0OTNiOGY1ZTk4OWFkZWU2Y2Qi.XMNLww.uvari0GZi4weboIecdtv9Vl8Jvg">