簡體   English   中英

在Flask中的WTform中創建動態字段

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM