2016-09-22 34 views
1

我想使用WTForms和Jinja2在Flask中創建不同的表單。我打電話給mysql,它有字段的類型。在Flask中的WTform中創建動態字段

所以即表可能是:

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中有form_id,所以我可以生成它然後驗證。

回答

4

添加字段動態

我覺得最好的是不過來創建一個空的形式,然後在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模型創建表格 類。

幫助程序類是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 - 鍊金做了一大堆與MyForm。該類本質上是這樣的:

class MyForm(Form): 
    title = StringField(validators=[InputRequired(), Length(max=5)]) 
    gender = SelectField(choices=[('male', 'male'), ('female', 'female')]) 
    text = TextField() 

WTForms-Alchemy的文檔似乎非常全面。我自己並沒有使用它,但如果我有類似的問題來解決,我一定會嘗試一下。