我一直在尝试实现一个“抽象”模式类,它将自动将 CamelCase(序列化)中的值转换为 Snake_case(反序列化)。
class CamelCaseSchema(marshmallow.Schema):
@marshmallow.pre_load
def camel_to_snake(self, data):
return {
utils.CaseConverter.camel_to_snake(key): value for key, value in data.items()
}
@marshmallow.post_dump
def snake_to_camel(self, data):
return {
utils.CaseConverter.snake_to_camel(key): value for key, value in data.items()
}
虽然使用类似的方法效果很好,但它并不能实现将 load_from
和 dump_to
应用于字段所实现的一切。也就是说,当反序列化出现问题时,它无法提供正确的字段名称。例如,我得到:
{'something_id': [u'不是有效的整数。']}
而不是 {'somethingId': [u'不是有效的整数。']}
。
虽然我可以对这些发出的错误进行后处理,但这似乎是一种不必要的耦合,如果我要使架构的使用完全透明,我希望避免这种耦合。
有什么想法吗?我尝试处理所涉及的元类,但复杂性有点难以承受,而且一切看起来都异常丑陋。
最佳答案
您正在使用 Marshmallow 2。Marshmallow 3 现已推出,我建议使用它。我的答案将适用于 Marshmallow 3。
在 Marshmallow 3 中,load_from
/dump_to
已被单个属性替换:data_key
。
实例化架构时,您需要更改每个字段中的data_key
。这将在字段实例化后发生,但我认为这并不重要。
您希望在实例化架构时尽快执行此操作,以避免不一致问题。执行此操作的正确时机是在检查 data_key
属性一致性之前的 Schema._init_fields
中间。但重复这个方法就太可惜了。此外,由于驼峰/蛇形大小写转换的性质,无论如何都可以在转换之前应用一致性检查。
由于 _init_fields
是私有(private) API,我建议在 __init__
末尾进行修改。
class CamelCaseSchema(Schema):
def __init__(self, **kwargs):
super().__init__(**kwargs)
for field_name, field in self.fields.items():
fields.data_key = utils.CaseConverter.snake_to_camel(field_name)
我没有尝试过,但我认为它应该有效。
关于python - 如何将 'load_from' 和 'dump_to' 应用于棉花糖模式中的每个字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57908057/