如何将“ load_from”和“ dump_to”应用于棉花糖模式中的每个字段?

时间:2019-09-12 13:41:08

标签: python marshmallow

我一直在尝试实现一个“抽象”模式类,该类将自动将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_fromdump_to应用于字段就可以实现。也就是说,当反序列化出现问题时,它无法提供正确的字段名称。例如,我得到: {'something_id': [u'Not a valid integer.']}而不是{'somethingId': [u'Not a valid integer.']}

虽然我可以对这些发出的错误进行后处理,但是这似乎是不必要的耦合,如果我想使模式的使用完全透明,我希望避免这种耦合。

有什么想法吗?我尝试解决涉及的元类,但是复杂性有点不堪重负,并且一切似乎都非常丑陋。

1 个答案:

答案 0 :(得分:2)

您正在使用棉花糖2。棉花糖3现已推出,我建议您使用它。我的答案将适用于棉花糖3。

在棉花糖3中,load_from / dump_to被单个属性data_key取代。

实例化架构时,您需要在每个字段中更改data_key。在字段实例化之后会发生这种情况,但我认为这并不重要。

您要在实例化架构时尽快执行该操作,以避免出现不一致问题。正确的时机应该在Schema._init_fields属性的一致性检查之前的data_key中间。但是复制这种方法将是可惜的。此外,由于骆驼/蛇格转换的性质,无论如何都可以在转换之前应用一致性检查。

而且由于_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)

我没有尝试过,但我认为应该可以。