2016-09-22 11 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_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モデルからForm クラスを作成できるヘルパークラスを提供します。

ヘルパークラスは、テーブルのスタイルでは、WTForms-Alchemyを使用したPython 2/3サンプルです。最初にパッケージwtforms-alchemyをインストールします。これにより、SQLAlchemyとWTFormも引き込まれます。上記のコードの印刷を実行

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のドキュメントは非常に包括的です。私はそれを自分で使ったことはありませんが、同様の問題が解決したら、私は間違いなくそれを試してみます。

関連する問題