I'm using WTForms-JSON and processing nested forms. I'd like to make an inner form optional, but if the inner form is present, I'd like its fields to be required. The problem I'm running into is that FormField
doesn't accept validators.
(Although I'm using WTForms-JSON, I believe this applies to vanilla WTForms as well.)
This code works but doesn't behave the way I want:
class InnerForm(Form):
foo_id = IntegerField("Foo ID", [Required()])
class OuterForm(Form):
inner = FormField(InnerForm)
The problem with the above code is that inner
is implicitly required. Oddly, while validate()
returns False
when inner
is omitted, errors
is empty.
This code doesn't doesn't work:
class InnerForm(Form):
foo_id = IntegerField("Foo ID", [Required()])
class OuterForm(Form):
inner = FormField(InnerForm, "Inner", [Optional()])
The latter produces this error:
TypeError: FormField does not accept any validators. Instead, define them on the enclosed form.
My question is: how can I make inner
optional, but require foo_id
if inner
is present?
The easiest way is to wrap the FormField
in a FieldList
, with max_entries
set to 1. FieldList
also supports validators, but since min_entries
is 0 by default you should not need any. The only annoyance will be that you will have to unwrap the inner form's data if it is available.
Thanks @aryeh for OptionalFormField
. I just put here my slightly improved (in my opinion) version:
class OptionalFormField(FormField):
def process(self, formdata, *args, **kwargs):
self._formdata = formdata
return super(OptionalFormField, self).process(formdata, *args, **kwargs)
def validate(self, *args, **kwargs):
if self._formdata:
for field_name in self._formdata.keys():
if field_name.startswith(self.name + self.separator):
return super(OptionalFormField, self).validate(*args, **kwargs)
return True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With