python - 我如何在 Marshmallow 中将 data_key 指定为可能的键名列表?

标签 python marshmallow

我想知道是否有任何方法可以将 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_nameUserName 等)“映射”到 名称

关于python - 我如何在 Marshmallow 中将 data_key 指定为可能的键名列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69158584/

相关文章:

python - 如何在 Python 中调试 MemoryError?跟踪内存使用的工具?

python - 如何更正损坏的 $PYTHONPATH?

Python - 在 0.17 中不推荐将 1d 数组作为数据传递,并将在 0.19 中引发 ValueError

mypy 的 Python Marshmallow 类型 stub

python - 使用 Flask-SQLAlchemy 和 Flask-Marshmallow 聚合连接查询

python - 如何在cocotb中强制使用python 3?

python - OpenCV - 读取带有 alpha channel 的灰度或单色图像

python - Flask、marshmallow - 嵌套字段的问题

python - 用 `data_key` 定义的 Marshmallow 字段和用 `attribute` 定义的 Marshmallow 字段有什么区别(标识符相反?)

python - Flask-Marshmallow 的 init_app() 真的有必要吗?