FormField
との組み合わせを使用してくださいFieldList
: ボイラー プレートを少し余分に使用し、永続化の際に手でバインドする必要がありますが、提出物を複数のフィールドに分割することで、同様の結果を得ることができます。
これは、WTForms へのDRYerアプローチであることの利点です。これを順守すると、フォームがよりスムーズに機能することがわかります。これは、ライブラリに組み込まれているデフォルトの動作で作業しているためです。ライブラリでは Widget クラスを組み合わせて使用できますが、私の経験では、一緒にうまく機能する組み合わせのサブセットはかなり限られています。Field
基本的な/Validator
の組み合わせに固執し、それらをFormField
/で構成すると、FieldList
物事ははるかにうまく機能します。
以下の例を参照してください。
コード
from collections import namedtuple
from wtforms import Form, FieldList, BooleanField, HiddenField, FormField
from webob.multidict import MultiDict
GroceryItem = namedtuple('GroceryItem', ['item_id', 'want', 'name'])
class GroceryItemForm(Form):
item_id = HiddenField()
want = BooleanField()
class GroceryListForm(Form):
def __init__(self, *args, **kwargs):
super(GroceryListForm, self).__init__(*args, **kwargs)
# just a little trickery to get custom labels
# on the list's checkboxes
for item_form in self.items:
for item in kwargs['data']['items']:
if item.item_id == item_form.item_id.data:
item_form.want.label =''
item_form.label = item.name
items = FieldList(FormField(GroceryItemForm))
item1 = GroceryItem(1, True, 'carrots')
item2 = GroceryItem(2, False, 'cornmeal')
data = {'items': [item1, item2]}
form = GroceryListForm(data=MultiDict(data))
print form.items()
生の HTML
<ul id="items">
<li>
carrots
<table id="items-0">
<tr>
<th></th>
<td><input id="items-0-item_id
" name="items-0-item_id" type="hidden" value="1"><input checked id="items-0-want" name="it
ems-0-want" type="checkbox" value="y"></td>
</tr>
</table>
</li>
<li>
cornmeal
<table id="items
-1">
<tr>
<th></th>
<td><input id="items-1-item_id" name="items-1-item_id" type="hidden" valu
e="2"><input id="items-1-want" name="items-1-want" type="checkbox" value="y"></td>
</tr>
</t
able>
</li>
</ul>
レンダリング結果
form.data
POST後の結果
{'items': [{'item_id': 1, 'want': True}, {'item_id': 2, 'want': False}]}