[英]create dynamic fields in WTform in Flask
我想使用WTForms和Jinja2在Flask中創建不同的表單。 我調用mysql,它具有字段類型。
所以即表可以是:
form_id | type | key | options | default_value
1 | TextField | title | | test1
1 | SelectField | gender |{'male','female'}|
2 | TextAreaField| text | | Hello, World!
然后我在form_id上查詢。 然后我想創建一個帶有WTforms的表單,其中包含返回的行的字段。
對於正常形式我做:
class MyForm(Form):
title = TextField('test1', [validators.Length(min=4, max=25)])
gender = SelectField('', choices=['male','female'])
def update_form(request):
form = MyForm(request.form)
if request.method == 'POST' and form.validate():
title = form.title.data
gender = form.gender.data
#do some updates with data
return .....
else:
return render_template('template.html',form)
#here should be something like:
#dict = query_mysql()
#new_form = MyForm(dict);
#render_template('template.html',new_form)
我認為最好是創建一個空表單,然后在for循環中添加字段,但是如果表單被回發,如果我沒有在類中定義它,我如何驗證表單? 我在表單中有form_id,所以我可以生成它然后驗證。
我認為最好是創建一個空表單,然后在for循環中添加字段,但是如果表單被回發,如果我沒有在類中定義它,我如何驗證表單?
在實例化表單之前,使用setattr
將字段添加到表單類 :
def update_form(request):
table = query()
class MyForm(Form):
pass
for row in table:
setattr(MyForm, row.key, SomeField())
form = MyForm(request.form)
但是,我認為你的問題是一個更大問題的一部分,我試圖在下面解決。
你的表似乎很好地映射到表單本身。 如果要從表中動態創建表單,可以自己編寫邏輯。 但是當支持的字段和選項范圍增加時,維護可能需要做很多工作。 如果您使用的是SQLAlchemy ,您可能需要查看WTForms-Alchemy 。 從介紹:
很多時候,使用SQLAlchemy構建現代Web應用程序時,您將擁有與模型緊密相關的表單。 例如,您可能有一個文章模型,並且您想要創建一個允許人們發布新文章的表單。 在這種情況下,在表單中定義字段類型和基本驗證器會非常耗時,因為您已經在模型中定義了字段。
WTForms-Alchemy提供了一個幫助器類,允許您從SQLAlchemy模型創建Form類。
幫助器類是ModelForm
,在表的樣式中,下面是帶有WTForms-Alchemy的Python 2/3示例。 首先安裝包wtforms-alchemy
,這也將引入SQLAlchemy和WTForms。
from __future__ import print_function
from __future__ import unicode_literals
import sqlalchemy as sa
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from wtforms_alchemy import ModelForm
engine = create_engine('sqlite:///:memory:')
Base = declarative_base(engine)
Session = sessionmaker(bind=engine)
session = Session()
class MyClass(Base):
__tablename__ = 'mytable'
id = sa.Column(sa.BigInteger, autoincrement=True, primary_key=True)
title = sa.Column(sa.Unicode(5), nullable=False)
gender = sa.Column(sa.Enum('male', 'female', name='gender'))
text = sa.Column(sa.Text)
class MyForm(ModelForm):
class Meta:
model = MyClass
form = MyForm()
print('HTML\n====')
for field in form:
print(field)
運行上面的代碼打印:
HTML
====
<input id="title" name="title" required type="text" value="">
<select id="gender" name="gender"><option value="male">male</option><option value="female">female</option></select>
<textarea id="text" name="text"></textarea>
如你所見,WTForms-Alchemy對MyForm
做了很多。 該課程基本上是這樣的:
class MyForm(Form):
title = StringField(validators=[InputRequired(), Length(max=5)])
gender = SelectField(choices=[('male', 'male'), ('female', 'female')])
text = TextField()
WTForms-Alchemy的文檔似乎非常全面。 我自己沒有用過它,但是如果我有類似的問題需要解決,我肯定會嘗試一下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.