如何将 'load_from' 和 'dump_to' 应用于棉花糖模式中的每个字段?
How to apply 'load_from' and 'dump_to' to every field in a marshmallow schema?
我一直在尝试实现一个 'abstract' 模式 class,它将自动将 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'Not a valid integer.']}
而不是 {'somethingId': [u'Not a valid integer.']}
.
虽然我可以 post 处理这些发出的错误,但这似乎是一种不必要的耦合,如果我要使模式的使用完全透明,我希望避免这种耦合。
有什么想法吗?我尝试处理所涉及的元classes,但复杂性有点让人难以承受,一切看起来都异常丑陋。
您正在使用 marshmallow 2。Marshmallow 3 现已推出,我建议您使用它。我的回答将适用于棉花糖 3。
在 marshmallow 3 中,load_from
/ dump_to
已被单个属性替换:data_key
.
实例化架构时,您需要在每个字段中更改 data_key
。这将在字段实例化之后发生,但我认为这不重要。
您希望在实例化模式时尽快执行此操作以避免不一致问题。正确的时机是在 Schema._init_fields
的中间,然后检查 data_key
属性的一致性。但是复制这种方法会很遗憾。此外,由于 camel/snake 大小写转换的性质,无论如何都可以在转换之前应用一致性检查。
并且由于 _init_fields
是私有的 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)
我没试过,但我认为它应该有用。
我一直在尝试实现一个 'abstract' 模式 class,它将自动将 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'Not a valid integer.']}
而不是 {'somethingId': [u'Not a valid integer.']}
.
虽然我可以 post 处理这些发出的错误,但这似乎是一种不必要的耦合,如果我要使模式的使用完全透明,我希望避免这种耦合。
有什么想法吗?我尝试处理所涉及的元classes,但复杂性有点让人难以承受,一切看起来都异常丑陋。
您正在使用 marshmallow 2。Marshmallow 3 现已推出,我建议您使用它。我的回答将适用于棉花糖 3。
在 marshmallow 3 中,load_from
/ dump_to
已被单个属性替换:data_key
.
实例化架构时,您需要在每个字段中更改 data_key
。这将在字段实例化之后发生,但我认为这不重要。
您希望在实例化模式时尽快执行此操作以避免不一致问题。正确的时机是在 Schema._init_fields
的中间,然后检查 data_key
属性的一致性。但是复制这种方法会很遗憾。此外,由于 camel/snake 大小写转换的性质,无论如何都可以在转换之前应用一致性检查。
并且由于 _init_fields
是私有的 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)
我没试过,但我认为它应该有用。