棉花糖-在同一模式中使用验证装饰器@validates_schema和@validates不起作用



我是棉花糖的新手,正在进行验证。我已经能够通过使用@validates或@validates_schema来使用自定义验证器,但它们似乎不能同时工作。以下可能吗?不确定我错过了什么。如果其中一个或另一个被注释掉,则相反的一个有效。有什么建议吗?

谢谢!!

class TestSchema(Schema):
field_1 = fields.String(required=True)
field_2 = fields.String(required=True)
field_3 = fields.String(required=True)
@validates_schema()
def validate_field1_less_field_2(self, data, **kwargs):
errors = dict()
if int(data["field_1"]) > int(data["field_2"]):
errors["field_1"] = ["field_1 must be less than field_2"]
if errors:
raise ValidationError(errors)

@validates('field_3')
def validate_field_3(self, field_3):
if any(field_3.upper() not in ['A', 'B', 'C'] for value in field_3):
raise ValidationError(f'Incorrect characters in field_3.')

try:
schema = TestSchema()
schema.load(json.loads(json_string))
except ValidationError as err:
print({err.messages})

我相信我已经发现了这个问题。我没有为@validates_schema装饰器使用选项"skip_on_field_errors=False"。添加后,我得到以下输出:

代码:

import json
from marshmallow import fields, ValidationError, validates, validate, validates_schema, Schema

class TestSchema(Schema):
# field_1 = fields.String(required=True)
# field_2 = fields.String(required=True)
field_1 = fields.Integer(required=True)
field_2 = fields.Integer(required=True)
field_3 = fields.String(required=True)
@validates_schema(skip_on_field_errors=False)
def validate_field1_less_field_2(self, data, **kwargs):
errors = dict()
if data["field_1"] > data["field_2"]:
# if int(data["field_1"]) > int(data["field_2"]):
errors["field_1"] = ["field_1 must be less than field_2"]
if errors:
raise ValidationError(errors)
@validates('field_3')
def validate_field_3(self, field_3):
if any(value.upper() not in ['A', 'B', 'C'] for value in field_3):
raise ValidationError(f'Incorrect characters in field_3.')

row =  {'field_1': '12', 'field_2': '6', 'field_3': 'aBx'}
json_string = json.dumps(row, indent=4)
print(f'json_string: {json_string}')
try:
schema = TestSchema()
schema.load(json.loads(json_string))
except ValidationError as err:
print({err})

输出:

json_string: {
"field_1": "12",
"field_2": "6",
"field_3": "aBx"
}
{ValidationError({'field_3': ['Incorrect characters in field_3.'], 'field_1': ['field_1 must be less than field_2']})}
Process finished with exit code 0

我还意识到,如果一个字段无效,比如提供一个需要int的字符串,你可能不想做任何模式级别的验证,因为这会导致错误-例如:如果field_1=512和field_2=5x2,你会得到:

if data['field_1'] > data['field_2']:
KeyError: 'field_2'

接下来,在使用@validates_schema对字段进行任何比较之前,我将使用默认的skip_on_field_errors=True来确保所有字段都是有效的。谢谢你的耐心,我希望这对将来的其他人有所帮助。

最新更新