如何制作Cerberus所需的规则取决于条件



我有一个很大的JSON文档,如果其他字段具有确切的值,则需要一些字段。例如

document = {'is_realty_address': False, 'postcode': 111111}

如果IS_REALTY_ADDRESS == false,则必须需要邮政编码。所有规则("必需"除外(都应用于文档中存在的字段,因此我的自定义规则是无声的,当我有

document = {'is_realty_address': False}

在我的情况下,符号没有帮助,因为我有很多"有条件的"字段,这些字段取决于许多不同的领域。因此,规则将使我的模式变得非常复杂。依赖项也无法正常工作。我尝试了:

{'postcode': {'dependencies': {'is_realty_address': False}, 'required': True}}

如果邮政编码未出现在文档中,则该返回错误,无论有什么值IS_REALTY_ADDRESS

v = Validator()
print(v.validate({'is_realty_address': False}, schema))
print(v.errors)
print(v.validate({'is_realty_address': True}, schema))
print(v.errors)

此代码返回:

False
{'postcode': ['required field']}
False
{'postcode': ['required field']}

我还尝试实现验证方法:

def _validate_conditional_required(self, conditional_required, field, value):
    """
    :param conditional_required:
    :param field:
    :param value:
    :return:
    The rule's arguments are validated against this schema:
    {'type': 'dict'}
    """
    for conditional_field, conditional_value in conditional_required.items():
        if self.document[conditional_field] == conditional_value and field not in self.document:
            self._error(field, errors.REQUIRED_FIELD)

使用模式

schema = {
    'is_realty_address': {'required': True, 'type': 'boolean'},
    'postcode': {'conditional_required': {'is_realty_address': False}},
}

但是,如果"邮政编码"不在文档中,则此规则不会运行。

有什么办法可以设置"条件要求"规则?我想查看此代码:

schema = {
    'is_realty_address': {'required': True, 'type': 'boolean'},
    'postcode': {'conditional_required': {'is_realty_address': False}},
}
v = Validator()
print(v.validate({'is_realty_address': False}, schema))
print(v.errors)
print(v.validate({'is_realty_address': True}, schema))
print(v.errors)

返回:

True
False
{'postcode': ['required field']}

我想出的是,可以通过"排除"one_answers" Oneof"规则的组合来解决我的问题

schema = {
'is_realty_address': {
    'required': True, 'type': 'boolean',
    'oneof': [{'excludes': 'postcode', 'allowed': [False]}, {'allowed': [True]}]
},
'postcode': {'type': 'integer', 'required': True}}
v = Validator()
print(v.validate({'is_realty_address': True}, schema))
print(v.errors)
print(v.validate({'is_realty_address': False, 'postcode': 111111}, schema))
print(v.errors)

此代码返回:

False
{'postcode': ['required field']}
False
{'is_realty_address': [{'oneof': ['none or more than one rule validate', {'oneof definition 1': ['unallowed value False'], 'oneof definition 0': ["'postcode' must not be present with 'is_realty_address'"]}]}]}

因此,对于此变体,模式不会非常复杂。

最新更新