简体   繁体   中英

Python: Cerberus coerce field when not empty

I would like to allow a field to be empty, but when it is not empty I want it to be Integer and range checked. I will need to coerce the field, when not empty, to int because it comes in as string. Is there a way to do this? My approach is below but that does not appear to work. I have done a bunch of research but have yet to see how to do this in what I have found.

Sample:

from cerberus import Validator

v = Validator()
v.schema = {
    'name': { 'type': 'string', 'minlength': 2},
    'age': {
        'oneof': [
            {'type': 'string', 'empty': True},
            {'type': 'integer', 'min': 5, 'max': 130, 'coerce': int, 'empty': False},
        ]
    }
}

if v.validate({'name': 'John', 'age': ''}):
    print('valid data')
else:
    print('invalid data')
    print(v.errors)

I get an error in validator creation:

Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
  File "C:\Users\ken\AppData\Roaming\Python\Python36\site-packages\cerberus\validator.py", line 562, in schema
    self._schema = DefinitionSchema(self, schema)
  File "C:\Users\ken\AppData\Roaming\Python\Python36\site-packages\cerberus\schema.py", line 82, in __init__
    self.validate(schema)
  File "C:\Users\ken\AppData\Roaming\Python\Python36\site-packages\cerberus\schema.py", line 262, in validate
    self._validate(schema)
  File "C:\Users\ken\AppData\Roaming\Python\Python36\site-packages\cerberus\schema.py", line 278, in _validate
    raise SchemaError(self.schema_validator.errors)
cerberus.schema.SchemaError: {'age': [{'oneof': [{'coerce': ['unknown rule']}]}]}

I don't have the reputation to comment, and I know this isn't a good answer but I'm not sure where else to put this.

The reason you are getting that error is because coerce isn't a valid rule within the context of a oneof rule. According to the docs , coerce is considered a normalization rule and those aren't allowed within any of the *of rules.

I know it's not a good solution, but you can use the check_with rule and write a custom validation function. Then in that function, you can simply dump all the check logic you have in there. Something like this:

def validate_age(f, v, e):
    # Perform your checks

my_schema = {
    "name": {
        "type": "string",
        "minlength": 2
    },
    "age": {
        "check_with": validate_age
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM