Cerberus:模式可以将一个值复制到多个字段吗?

Cerberus: Can the schema copy a value to multiple fields?

我想获取如下所示的输入文档,并将 'foo' 键复制到具有不同强制和验证的多个字段,以获得如下内容:

>>> input_doc = {'foo': 10}
>>> coercions = {'foo': {'copy_to': 'bar', 'coerce': str}, 'bar': {'coerce': add_five}}
>>> v = Validator(coercions)
>>> v.normalized(input_doc)
{'foo': '10', 'bar': 15}

我知道我可以在 将值复制到其他键之前 馈入 Cerberus,但如果我能在理想的模式中完成这一切。

Cerberus 具有 'rename' 规范化规则,该规则在其他强制和验证之前运行,但如果您将容器传递给它,它只是将密钥重命名为该容器,而不是复制到每个容器。

我认为 custom rule 可以处理它,只是它在此过程中运行得太晚了。理想情况下,我需要复制预验证甚至预强制。

也许我对 Cerberus 的要求太多了,但它非常接近成为满足我的数据处理需求的一站式解决方案。

下面的方法有效,但有点老套。仍然想知道是否有更好的方法来处理这个问题。

基本上,我制作了一个自定义验证器 class 并为其提供了一个自定义 rename_handler 方法,以便它可以直接访问文档。 KEY_MAP 是一个字典,它告诉验证器将哪些字段名称复制到哪里,因为您不能将参数传递给 rename_handler.

from cerberus import Validator

class CustomValidator(Validator):
    KEY_MAP = {'foo': 'bar'}

    def _normalize_coerce_copy_field(self, field):
        copy = self.KEY_MAP[field]
        self.document[copy] = self.document[field]

        return field


>>> input_doc = {'foo': 10}
>>> coercions = {'foo': {'rename_handler': 'copy_field', 'coerce': str}, 'bar': {'coerce': lambda x: x + 5}}
>>> v = CustomValidator(coercions)
>>> v.normalized(input_doc)
{'foo': '10', 'bar': 15}