Solution
from collections import defaultdict
class AllocationForm(Form):
project_id = StringField('Project ID')
# ...
class DeallocationForm(Form):
project_id = StringField('Project ID')
# ...
class RequestForm(FlaskForm):
allocations = FieldList(FormField(AllocationForm))
deallocations = FieldList(FormField(DeallocationForm))
def validate(self):
data_fields = defaultdict(list)
for field in (self.allocations, self.deallocations):
for form in field:
if form.project_id.data:
data_fields[form.project_id.data].append(form.project_id)
success = True
for data,fields in data_fields.items():
if len(fields) > 1:
for field in fields:
msg = 'A project ID cannot appear more than once in a request'
field.errors += (msg,)
success = False
return success and super().validate()