How to validate that at least one field is present of multiple with formencode validators?

1k views Asked by At

With Python Formencode validators, there are chained_validators RequireIfMissing and RequireIfPresent that allow for requirements given the state of other fields being there or not. It seems to only work for single fields meaning if one field is missing, require another or if one field is present, require another. How does one require at least one of many fields?

1

There are 1 answers

0
jchysk On

The class below: RequireAtLeastOne will take a list of fields and will only pass if at least a single one of the fields is present as demonstrated with the successes and failures at the bottom.

from formencode import Schema, validators, Invalid
from formencode.validators import FormValidator


class RequireAtLeastOne(FormValidator):
    choices = []
    __unpackargs__ = ('choices',)
    def _convert_to_python(self, value_dict, state):
        for each in self.choices:
            if value_dict.get(each) is not None:
                return value_dict
        raise Invalid('You must give a value for %s' % repr(self.choices), value_dict, state)


class ValidateThings(Schema):
    field1 = validators.String(if_missing=None)    
    field2 = validators.String(if_missing=None)
    field3 = validators.String(if_missing=None)
    chained_validators = [RequireAtLeastOne(['field1', 'field2', 'field3'])]


""" Success """        
params = ValidateThings().to_python({"field2": 12})
params = ValidateThings().to_python({"field2": 12, "field3": 126})
params = ValidateThings().to_python({"field1": "foo", "field2": 12, "field3": 126})

""" Failure """
params = ValidateThings().to_python({})