web-dev-qa-db-ja.com

wtformsを使用して入力フィールドを動的に追加する

この問題にどのようにアプローチするかはよくわかりません。私はそこに着くといいのですが。

たとえば、ページにアドレスでいっぱいのテーブルがあります。これらのカウントは動的です(5または10またはその他のカウントである可能性があります)。そして、1ページで編集できるようにしたいと思います。

私のアプローチは、wtformsを使用してフォームを作成し、1つのアドレスを編集して、それをjinja2で乗算することでしたfor loopそしてhtmlプロパティにnameidを追加しますloop.index0反復から、データの各行を手動で抽出し、評価したいときにフォームに戻すことができます。

したがって、この例のフォームは次のようになります。

class AdressForm(Form):
    name = TextField()

これで、テンプレートのアプローチは次のようになります(1つの入力フィールドに分解します)。

{% for address in addresses %}
    {{ forms.render_field(addressform.name, id = "name_" ~ loop.index0, 
                          name = "name_" ~ loop.index0, value = address.name) }}
{% endfor %}

(forms.render_fieldは、多くのチュートリアルで使用されているように、wtformsのフィールド関数に適切なクラスを指定するための単なるマクロです)

Wtformsは最初のフォームの変数名からname html-paramterを作成するため、nameパラメーターをフィールド関数に手動で渡すことができないため、これは機能しません。

レンダリングしたいフォームの名前にプレフィックスまたはポストフィックスを追加する方法はありますか?それとも、これはXYの問題であり、私のアプローチは完全に間違っています。

または私はそれをすべて自分で明白にしますか(私は本当にこれを避けようとします)

14
muthan

WTFormsには、 FormField というメタフィールドと FieldList という別のメタフィールドがあります。これら2つを組み合わせると、必要なものが得られます。

class AddressEntryForm(FlaskForm):
    name = StringField()

class AddressesForm(FlaskForm):
    """A form for one or more addresses"""
    addresses = FieldList(FormField(AddressEntryForm), min_entries=1)

AddressesFormにエントリを作成するには、辞書のリストを使用するだけです。

user_addresses = [{"name": "First Address"},
                  {"name": "Second Address"}]
form = AddressesForm(addresses=user_addresses)
return render_template("edit.html", form=form)

次に、テンプレートで、サブフォームをループします。

{% from 'your_form_template.jinja' import forms %}
{% for address_entry_form in form.addresses %}
    {{ address_entry_form.hidden_tag() }}
    {# Flask-WTF needs `hidden_tag()` so CSRF works for each form #}
    {{ forms.render_field(address_entry_form.name) }}
{% endfor %}

WTFormsは自動的に名前とIDに正しくプレフィックスを付けるため、データをポストバックすると、form.addresses.dataを取得して、更新されたデータを含む辞書のリストを取得できます。

26
Sean Vieira

Sean Vieiraの回答StringFields(以前はTextField)には最適ですが、動的なSelectFieldsには少し注意が必要です。動的なSelectFieldswtformsで実装する方法に興味のある人は、 https://stackoverflow.com/a/57548509/7781935 を参照してください。

1
Ty Hitzeman