Using FieldList and FormField

python, wtforms

Solution

Explanation

In your `data` or `formdata` keyword arguments for the `Form` you just need an dictionary with a `key` that matches the `FieldList` subfield that contains an iterable. The items in that iterable need in turn have items w/ attributes that match with `FieldList`'s list of fields.

If you follow the example below I get nested Forms that are pre-populated just fine.

The Code

from collections import namedtuple

from wtforms import validators
from wtforms import Form
from wtforms import SelectField
from wtforms import BooleanField
from wtforms import TextField
from wtforms import FieldList
from wtforms import FormField

from webob.multidict import MultiDict

# OP's Code
class FullNameMixIn():
    full_name = TextField(
        'Full name', [
            validators.required(message=u"Full name is required")
        ])

class GroupRoleForm(Form):
    group =BooleanField('Group', default=False)
    role = SelectField(
            'Role',choices=[
            ("none", "----------"), 
            ('approver', 'Approver'),
            ('editor', 'Editor')
            ])

class AdminEditUserForm(Form, FullNameMixIn):
    group_roles = FieldList(FormField(GroupRoleForm))

# create some groups
Group = namedtuple('Group', ['group', 'role'])
g1 = Group('group-1', 'none')
g2 = Group('group-2', 'none')

# drop them in a dictionary 
data_in={'group_roles': [g1, g2]}

# Build form 
test_form = AdminEditUserForm(data=MultiDict(data_in))

# test print
print test_form.group_roles()

The Rendered HTML(Truncated)

<ul id="group_roles">
   <li>
      <label for="group_roles-0">Group Roles-0</label> 
      <table id="group_roles-0">
         <tr>
            <th><label for="gr
               oup_roles-0-group">Group</label></th>
            <td><input checked id="group_roles-0-group" name="group_roles-0-group" type="checkbox" value="y"><
               /td>
         </tr>
         <tr>
            <th><label for="group_roles-0-role">Role</label></th>
            <td>
               <select id="group_roles-0-role" name="group_roles-0-role">
                  <option
                     selected value="none">----------</option>
                  <option value="approver">Approver</option>
                  <option value="editor">Editor</option>
               </select>
            </td
               >
         </tr>
      </table>
   </li>
   <li>
      <label for="group_roles-1">Group Roles-1</label> 
      <table id="group_roles-1">
         <tr>
            <th><label for="group_roles-1-gro
               up">Group</label></th>
            <td><input checked id="group_roles-1-group" name="group_roles-1-group" type="checkbox" value="y"></td>
         </tr>
         <tr>
            <t
               h>
            <label for="group_roles-1-role">Role</label></th>
            <td>
               <select id="group_roles-1-role" name="group_roles-1-role">
                  <option selected value
                     ="none">----------</option>
                  <option value="approver">Approver</option>
                  <option value="editor">Editor</option>
               </select>
            </td>
         </tr>
      </table>
      <
      /li>
</ul>

...

Problem

We have the following forms and we are trying to create list of `GroupRoleForms` for each group. ``` class FullNameMixIn(): full_name = TextField( 'Full name', [ validators.required(message=u"Full name is required") ]) class GroupRoleForm(Form): group =BooleanField('Group', default=False) role = SelectField( 'Role',choices=[ ("none", "----------"), ('approver', 'Approver'), ('editor', 'Editor') ]) class AdminEditUserForm(Form, FullNameMixIn): group_roles = FieldList(FormField(GroupRoleForm)) ``` How can we create a `AdminEditUserForm` instance that contains a pre-populated list of `GroupRoleForms`? At the moment we are trying to do it this way: ``` form = forms.AdminEditUserForm() for group in company.groups: group_role_form = forms.GroupRoleForm() group_role_form.group.label = group.name group_role_form.group.name = group.id form.group_roles.append_entry(group_role_form) return dict(edit_user_form = form ) ```

Original source