この問題にどのようにアプローチするかはよくわかりません。私はそこに着くといいのですが。
たとえば、ページにアドレスでいっぱいのテーブルがあります。これらのカウントは動的です(5または10またはその他のカウントである可能性があります)。そして、1ページで編集できるようにしたいと思います。
私のアプローチは、wtformsを使用してフォームを作成し、1つのアドレスを編集して、それをjinja2で乗算することでしたfor loop
そしてhtmlプロパティにname
とid
を追加します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の問題であり、私のアプローチは完全に間違っています。
または私はそれをすべて自分で明白にしますか(私は本当にこれを避けようとします)
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
を取得して、更新されたデータを含む辞書のリストを取得できます。
Sean Vieiraの回答StringFields
(以前はTextField
)には最適ですが、動的なSelectFields
には少し注意が必要です。動的なSelectFields
をwtforms
で実装する方法に興味のある人は、 https://stackoverflow.com/a/57548509/7781935 を参照してください。