I have validation rules in Cerberus that require a custom validator. When accessing fields in self.document
, I have to also validate those fields are present, even if using the "required"
flag. I am looking for a way for the "required"
flag to handle this for me.
For example, say I have a dictionary named data
with arrays a
and b
and the stipulations that both a
and b
are required and that len(a) == len(b)
.
# Schema
schema = {'data':
{'type': 'dict',
'schema': {'a': {'type': 'list',
'required': True,
'length_b': True},
'b': {'type': 'list',
'required': True}}}}
# Validator
class myValidator(cerberus.Validator):
def _validate_length_b(self, length_b, field, value):
"""Validates a field has the same length has b"""
if length_b:
b = self.document.get('b')
if not len(b) == len(value):
self._error(field, 'is not equal to length of b array')
This works fine if a
and b
are present:
good = {'data': {'a': [1, 2, 3],
'b': [1, 2, 3]}}
v = myValidator()
v.validate(good, schema)
# True
bad = {'data': {'a': [1, 2, 3],
'b': [1, 3]}}
v.validate(bad, schema)
# False
v.errors
# {'data': [{'a': ['is not equal to length of b array']}]}
However, if b
is missing, it returns a TypeError
from len()
.
very_bad = {'data': {'a': [1, 2, 3]}}
v.validate(very_bad, schema)
# TypeError: object of type 'NoneType' has no len()
How can I get validate
to return False
instead (as b
is not present)? My desired output is below:
v.validate(very_bad, schema)
# False
v.errors
# {'data': ['b': ['required field']]}