我遇到了一个问题,我希望有人能指出我正确的方向。 我想使用棉花糖来验证具有嵌套模式的结构。 这是一个例子:
from marshmallow import Schema, fields
class userAddress(Schema):
street = fields.Str(required=True)
city = fields.Str(required=False)
zipcode = fields.Int(required=True)
class user(Schema):
name = fields.Str(required=True)
address = fields.Nested(userAddress, required=False, allow_none=True, allow_blank=True)
user_instance = user()
user_data1 = {
"name": "John Doe",
"address": {
"street": "Road to nowhere",
"city": "St. Elsewhere",
"zipcode": 666
}
}
user_data2 = {
"name": "John Doe, Jr.",
"address": {}
}
我想要实现的是,两个 user_data 字典都经过验证,没有问题。如果键
address
存在,相应的字典应与模式 userAddress
中的定义匹配。但如果键 address
不存在或值为空字典,这是可以接受的。
但是这不起作用,结果如下:
>>> user_instance.validate(user_data1)
{}
>>> user_instance.validate(user_data2)
{'address': {'zipcode': ['Missing data for required field.'], 'street': ['Missing data for required field.']}}
>>>
不接受 user_data2 中
address
的空字典。
我尝试在
partial=True
中使用 validate
,但随后也接受了缺失的 name
。
尝试使用 fields.Raw() 而不是 Nested()
from marshmallow import Schema, fields
class userAddress(Schema):
street = fields.Str(required=True)
city = fields.Str(required=False)
zipcode = fields.Int(required=True)
class user(Schema):
name = fields.Str(required=True)
address = fields.Raw(userAddress)
user_instance = user()
user_data1 = {
"name": "John Doe",
"address": {
"street": "Road to nowhere",
"city": "St. Elsewhere",
"zipcode": 666
}
}
user_data2 = {
"name": "John Doe, Jr.",
"address": {}
}
一种方法是在加载之前清理空字典:
class userAddress(Schema):
street = fields.Str(required=True)
city = fields.Str(required=False)
zipcode = fields.Int(required=True)
class user(Schema):
name = fields.Str(required=True)
address = fields.Nested(userAddress, required=False, allow_none=True)
@pre_load
def clearemptydicts(self, data, **kwargs):
for k, v in data.items():
if isinstance(v, dict) and len(v) == 0:
data[k] = None
return data
user_instance = user()
user_data1 = {
"name": "John Doe",
"address": {
"street": "Road to nowhere",
"city": "St. Elsewhere",
"zipcode": 666
}
}
user_data2 = {
"name": "John Doe, Jr.",
"address": {}
}
print(user_instance.validate(user_data1))
print(user_instance.validate(user_data2))