Cerberus accept as valid the empty values

4.3k views Asked by At

Trying to get this validation as acceptable True, where any of the fields could be empty: True (default i know), but when not empty than all the sequential conditionals must apply.

SCHEMA v = Validator()

schm = {'l_addrsch': {'type': 'string', 'empty': True, 'allowed': ['m', 'o', 'e', 'M', 'O', 'E'], 'dependencies': ['l_nrefaddr', 'l_refaddr']},
    'l_nrefaddr': {'type': 'integer', 'empty': True, 'dependencies': ['l_addrsch', 'l_refaddr']},
    'l_refaddr': {'type': 'integer', 'empty': True, 'dependencies': ['l_addrsch', 'l_nrefaddr']}}

POST val = v.validate(p, schema)

{ 
"l_addrsch" : "",
"l_nrefaddr" : "",
"l_refaddr" :  ""
}

RESPONSE

    [
    {
        "l_addrsch": [
            "unallowed value "
        ],
        "l_nrefaddr": [
            "must be of integer type"
        ],
        "l_refaddr": [
            "must be of integer type"
        ]
    }
]

Hope i was not too confuse.

EDIT 1: tried this as mentioned on normalizing rules 'default' :

schema = {'l_addrsch': {'type': 'string', 'default': '', 'allowed': ['', 'm', 'o', 'e', 'M', 'O', 'E'], 'dependencies': ['l_nrefaddr', 'l_refaddr']},
                'l_nrefaddr': {'type': 'integer', 'default': 0, 'dependencies': ['l_addrsch', 'l_refaddr']},
                'l_refaddr': {'type': 'integer', 'default': 0, 'dependencies': ['l_addrsch', 'l_nrefaddr']}

POST:

   { "l_addrsch" : "",
    "l_nrefaddr" : "",
    "l_refaddr" :  ""}

But seems that i still missing something to get it working for the integers

[
    {
        "l_nrefaddr": [
            "must be of integer type"
        ],
        "l_refaddr": [
            "must be of integer type"
        ]
    }
]
2

There are 2 answers

3
Mekicha On

From the doc:

If False, validation of an iterable value will fail if it is empty. Setting it to True manually is pointless as it behaves like omitting the rule at all

To set default values, use the normalization rule instead. http://docs.python-cerberus.org/en/stable/normalization-rules.html#default-values

Something like this:

'kind': {'type': 'string', 'default': ''}
0
funky-future On

The validation fails for two reasons:

  1. '' is not defined as allowed value, this ruleset should achieve what you want for the l_addrsch field:

    'l_addrsch': {'type': string, 'allowed': ('', 'm', 'o', 'e', 'M', 'O', 'E'), 'required': True}

    Update: With Cerberus 1.2 it will be possible to have an empty field (if permitted) that will not be checked for allowed values (see this commit).

  2. As a string ('') is passed as value for the two other fields, it will of course fail with a type constrained to integer. You should add a coercion of the input value, if '' always means 0.