Marshmallow Schema是否支持反序列化时的输入数据嵌套字段查找?
关于Marshmallow Schema反序列化时嵌套字段查找的问题
你遇到的情况其实是Marshmallow的data_key参数默认不支持通过点分隔符来直接定位嵌套层级的字段——这就是为什么你用data_key="child.fname"时,反序列化后得到空结果的原因。Marshmallow会把"child.fname"当作一个完整的顶级字段名去查找,而你的输入数据里并没有这个顶级字段,自然匹配不到。
那该怎么实现你要的需求呢?这里有几个可行的方案:
方案1:使用Nested Schema结合字段筛选
如果你只是想提取嵌套对象里的某个字段,可以先定义子Schema,再用Nested字段并指定only参数来获取目标字段:
from marshmallow import Schema, fields class ChildSchema(Schema): fname = fields.String() class ParentSchema(Schema): child_name = fields.Nested(ChildSchema, data_key="child", only=["fname"]) data = {"child": {"fname": "John", "lname": "Doe"}} result = ParentSchema().load(data) # 输出: {'child_name': {'fname': 'John'}}
如果想直接把fname映射为平级的child_name,可以在反序列化后手动处理,或者用下面的方案2。
方案2:自定义字段或使用Method字段
通过自定义字段或者Method字段来手动提取嵌套路径的数值:
from marshmallow import Schema, fields class ParentSchema(Schema): child_name = fields.Method("get_child_fname") def get_child_fname(self, obj): return obj.get("child", {}).get("fname") data = {"child": {"fname": "John", "lname": "Doe"}} result = ParentSchema().load(data) # 输出: {'child_name': 'John'}
也可以用post_load钩子来统一处理数据:
from marshmallow import Schema, post_load class ParentSchema(Schema): @post_load def extract_child_name(self, data, **kwargs): return {"child_name": data.get("child", {}).get("fname")} result = ParentSchema().load(data) # 输出: {'child_name': 'John'}
方案3:升级到Marshmallow 3.18.0+(如果可行)
从Marshmallow 3.18.0版本开始,官方新增了对**点分隔的嵌套data_key**的支持!如果你能升级版本,只需要保持你最初的写法就能生效:
from marshmallow import Schema, fields class ParentSchema(Schema): child_name = fields.String(data_key="child.fname") data = {"child": {"fname": "John", "lname": "Doe"}} result = ParentSchema().load(data) # 输出: {'child_name': 'John'}
总结一下:你使用的3.14.1版本本身不支持这种嵌套路径的data_key,但可以通过方案1或2来实现需求;如果能升级到3.18.0及以上,就能直接用你最初的写法达成目标。
内容的提问来源于stack exchange,提问作者renatodamas
相关产品推荐
相关产品推荐

