Chase
Chase

Reputation: 3105

WTForms removing fields per-instance with FormField and FieldList

I have a base class form for PersonForm that looks something like this:

class PersonForm(Form):
    '''Re-usable form for parents and spouses and children and grandchildren'''
    name = StringField('Name', validators=[])
    maiden_name = StringField('Maiden Name', validators=[])
    partner = StringField('Spouse or Partner First Name', validators=[])
    deceased = BooleanField('Deceased')
    owns_monkey = BooleanField('Owns Monkey')
    note = StringField('Note', validators=[])

In another form I'm referencing that base class and using it in a FieldList, something like this:

class ParentsForm(FlaskForm):
    '''Who are the parents?'''
    parents = FieldList(FormField(PersonForm), min_entries=2)
    submit = SubmitField('Next')

When the ParentsForm is rendered it will include at least 2 instances of the Person form. But let's say that asking whether these people own a monkey or not is irrelevant for the current form, so I'd like to remove it before it is rendered.

The WTForms documentation for Removing Fields Per-Instance says you can simply use the del form.field syntax, but it does not specify if this is possible for when using FieldList.

If I were to do:

form = ParentsForm()
print(form.parents)

instead of referencing a Python object, it simply gives me an HTML unordered list composed of the two PersonForm entries. This means that I couldn't do del form.parents.owns_monkey to remove those fields.

Is there a way to achieve this?

Upvotes: 0

Views: 48

Answers (1)

Chase
Chase

Reputation: 3105

I figured it out and will post what I discovered in case anyone else gets stuck here.

You can access each individual FieldList instance via form.parents.entries where entries is an attribute of FieldList. (form.parents is just a reference to what I named that enclosed FieldList in my ParentsForm, it isn't a special keyword).

Each entry is of type FormField, whose attributes contains a form entry, which is a reference to the singular PersonForm instance.

This means you can use:

form = ParentsForm()

for parent in form.parents.entries:
    del parent.form.owns_monkey

Hopefully someone else finds this useful.

Upvotes: 0

Related Questions