Marshmallow没有从嵌套列表返回验证错误



我从Marshmallow开始,我想用它来验证我的数据(来自api请求)。我创建了以下schema:

from marshmallow import fields, Schema
from marshmallow.validate import Range
class RequestTopSchema(Schema):
upperTarget = fields.Float(required=True, validate = validate.Range(min = 0.0, max = 80.0))
lowerTarget = fields.Float(required=True)
data = fields.Nested("Values", many = True, required = False)

class Values(Schema):
timestamp = fields.String(required=True)
value = fields.Float(required =True, validate = Range(min = 0.0, max = 100.0))
request_top_schema = RequestTopSchema()

然后我传入以下数据:

request_data = {
"lowerTarget": 10,
"upperTarget": 20,
"data": [
{
"timestamp": "2020-01-01 11:20:00+02:00",
"value": 156.7
},
{
"timestamp": "2020-01-01 11:25:00+02:00",
"value": "46.7"
}
]
}
request_top_schema.validate(request_data)

和接收:

{}

但是,由于我的第一个值大于100,第二个值是字符串格式-我预计这会返回两个错误。

在顶层,至少有一些东西可以工作——如果我传入:

request_data = {
"lowerTarget": "20",
"upperTarget": 180,
"data": [
{
"timestamp": "2020-01-01 11:20:00+02:00",
"value": 156.7
},
{
"timestamp": "2020-01-01 11:25:00+02:00",
"value": "46.7"
}
]
}
request_top_schema.validate(request_data)

我收到:{'upperTarget': ['Must be greater than or equal to 0.0 and less than or equal to 100.0.']}因此,我确实收到超出范围的验证错误,但是,我的lowerTarget是字符串并没有失败。

UPDATE -我已经设法解决了这个问题。问题是将嵌套模式作为字符串传递。如果我将它们更改为对象,它将按预期工作。

但是仍然存在一个问题:fields.Float()接受浮点数作为字符串"100.0"。这似乎是一个已知的问题:https://github.com/marshmallow-code/marshmallow/pull/755当前的解决方案是使用自定义float字段。


class Float(fields.Float):
def _deserialize(self, value, attr, data, **kwargs):
if isinstance(value, float) or isinstance(value, int):
return value
else:
raise ValidationError('Field should be int or float')
class RequestTopSchema(Schema):
upperTarget = Float(required=True, validate = validate.Range(min = 0.0, max = 80.0))
lowerTarget = Float(required=True)
data = fields.Nested(Values, many = True, required = False)

class Values(Schema):
timestamp = fields.String(required=True)
value = fields.Float(required =True, validate = Range(min = 0.0, max = 100.0))