0

我使用 Python 包cerberus来验证我的有效负载这是我的问题:

仅当来自另一个模式的某些字段具有精确值时,我才需要设置一个字段。就像是:

    "key2": {
      "type": "string",
      "required": \\\ true if dict1.key1 == 'valueX' else false \\\
    }

所以我的架构应该是这样的:

"dict1": {
  "type": "dict",
  "schema": {
    "key1": {
      "type": "string",
      "required": true
    }
  }
},
"dict2": {
  "type": "dict",
  "schema": {
    "key2": {
      "type": "string",
      "required": \\\ true if dict1.key1 == 'valueX' else false \\\
    }
  }
}

有人知道方法,如何实现吗?谢谢

4

3 回答 3

0

我已经阅读了文档,但还没有找到答案。在您的示例中,我不确定它是否真的有效。此外,我认为依赖项的工作方式与我的示例不同。但也许我错了。

看起来子模式中的依赖项不起作用。您的示例返回错误消息:

from cerberus import Validator
schema = {"dict1": {
        "type": "dict",
        "schema": {
            "key1": {
                "type": "string",
                "required": True,
                "allowed": ["valueX"]
            }
        }
    },
    "dict2": {
        "type": "dict",
        "schema": {
            "key2": {  # required if dependency matches
                "type": "string",
                "dependencies": {
                    "dict1.key1": ["valueX"]
                }
            }
        }
    }
}
payload = {
    "dict1": {
                "key1": 'valueX'
            },
     "dict2": {
                "key2": 'some_value'
            }       
    }

validator = Validator(schema)
if validator(payload):
    print('Super!')
else:
    print(str(validator.errors))

有错误:

{'dict2': [{'key2': ["depends on these values: {'dict1.key1': ['valueX']}"]}]}

但是当我尝试为“dict2”设置依赖项时它起作用了

schema = {"dict1": {
        "type": "dict",
        "schema": {
            "key1": {
                "type": "string",
                "required": True#,
                #"allowed": ["valueX"]
            }
        }
    },
    "dict2": {
        "type": "dict",
        "dependencies": {
                    "dict1.key1": "sms"
                },
        "schema": {
            "key2": {  # required if dependency matches
                "type": "string"
            }
        }
    }
}

如果我错了,请告诉我。该解决方案真的会帮助我。谢谢

于 2020-05-26T11:32:13.697 回答
0

我也在为此苦苦挣扎,这是一个较短的示例,我希望它可以使用依赖项来工作。我将其发布为答案(但社区 wiki),因为代码块在评论中往往看起来不太好。希望没关系,而不是创建一个单独的问题。

更短的可重现示例

schema = {
    'field1': {
        'required': True
    }, 
    'field2': {
        'required': True,      
         'dependencies': {
             'field1': 'one'
         }
    }
}

>>> document = {'field1': 'two'}
>>> v.validate(document, schema)
False
>>> print(v.errors)

{'field2': ['required field']}

根据我的理解,如果字段 1 等于“一”,则需要执行上述操作。

我的第二次尝试是不使其成为必需:

schema = {
    'field1': {
        'required': True
    }, 
    'field2': {
        'required': False,      
         'dependencies': {
             'field1': 'one'
         }
    }
}

然而,这通过了测试:

>>> document = {'field1': 'one'}
>>> v.validate(document, schema)
True
>>> print(v.errors)

{}

只有当“field1”没有批准的值时,如果我尝试在“field2”中提供一个值,它们才会失败:

>>> document = {'field1': 'two', 'field2': 'test'}
>>> v.validate(document, schema)
False
>>> print(v.errors)

{'field2': ["depends on these values: {'field1': 'one'}"]}

所以我认为 Cerberus 不支持这个用例,或者如果支持,我还没有找到合适的组合。

于 2020-06-09T19:08:22.250 回答
-1

大多数时候,您会在图书馆的文档中找到解决方案。
您正在寻找的是“依赖项”下

的 Cerberus 文档的链接和相应的部分可以在这里找到:
https ://docs.python-cerberus.org/en/stable/validation-rules.html#dependencies

在文档中它说:


提供映射时,不仅所有依赖项都必须存在,而且它们的任何允许值都必须匹配。


还支持使用点符号声明对子文档字段的依赖关系:


对于您的示例,这仅意味着,如果您的要求绑定到一个值,则该值必须与“允许”规则指定的任何值匹配。

如果您的要求绑定到模式,则可以通过点表示法指定该模式及其子模式。

应该适合您的解决方案如下所示:

"dict1": {
    "type": "dict",
    "schema": {
        "key1": {
            "type": "string",
            "required": True,
            "allowed": ["valueX"]
        }
    }
},
"dict2": {
    "type": "dict",
    "schema": {
        "key2": {  # required if dependency matches
            "type": "string",
            "dependencies": {
                "dict1.key1": ["valueX"]
            }
        }
    }
}

我不确定当您根本不指定任何“允许”规则时这是否也有效,但我几乎猜它应该。

于 2020-05-24T21:49:39.957 回答