我想知道是否有任何方法可以将 Marshmallow 中的 data_key
指定为列表,或者可以通过任何其他方式来说明某些特定字段(如 username
)可以与不同的键名,例如 name、user_name、UserName、userName
这是我当前模式的示例
class PersonSchema(Schema):
name = fields.String(data_key="user_name")
age = fields.Integer()
@post_load
def create_person(self, data, **kwargs):
return Person(**data)
最佳答案
目前(从版本 3.13.0 开始),这是 data_key
的处理方式 (source):
...
key = field_obj.data_key if field_obj.data_key is not None else attr_name
ret[key] = value
return ret
...
因此,如果您尝试将元组指定为 data_key
(列表将无法工作,因为它不可哈希),整个元组将构成字典的键 ret
(见上文)。因此,它不适用于单个字符串。
解决方法是使用 pre_load
装饰器,例如:
from marshmallow import Schema, fields, pre_load, ValidationError
class PersonSchema(Schema):
name = fields.String()
age = fields.Integer()
@pre_load
def process_data_key(self, data, **kwargs):
names = [name for name in data.keys()
if name in ("name", "user_name", "UserName", "userName")]
if len(names) > 1:
raise ValidationError('Multiple values for field "name".')
if names: # check if any name was included at all
data["name"] = data.pop(names[0])
return data
s = PersonSchema()
data = {"name": "Mike", "age": "32"}
result = s.load(data)
print(result) # {'name': 'Mike', 'age': 32}
data = {"user_name": "Mike", "age": "32"}
result = s.load(data)
print(result) # {'name': 'Mike', 'age': 32}
data = {"UserName": "Mike", "age": "32"}
result = s.load(data)
print(result) # {'name': 'Mike', 'age': 32}
data = {"name": "Mike", "UserName": "Mike", "age": "32"}
try:
result = s.load(data)
except ValidationError as err:
print(err.messages) # {'_schema': ['Multiple values for field "name".']}
data = {"age": "32"}
result = s.load(data)
print(result) # {'age': 32}
上面的想法是将 name
的所有不同变体(即 user_name
、UserName
等)“映射”到 名称
。
关于python - 我如何在 Marshmallow 中将 data_key 指定为可能的键名列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69158584/