【问题标题】:How to make cerberus required rule depends on condition如何制作 cerberus 所需的规则取决于条件
【发布时间】:2018-02-14 14:33:25
【问题描述】:

我有一个很大的 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']}

【问题讨论】:

    标签: python json validation cerberus


    【解决方案1】:

    我发现,我的问题可以通过“排除”和“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'"]}]}]}
    

    因此,使用此变体的架构不会过于复杂。

    【讨论】:

    • 你应该改为:schema = { 'is_realty_address': { 'required': True, 'type': 'boolean', 'oneof': [{'excludes': 'postcode', 'allowed': [False]}, {'dependencies': 'postcode', 'allowed': [True]}] }, 'postcode': {'type': 'integer'}}
    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    相关资源
    最近更新 更多