0

field_1默认情况下必须为 0,但不允许使用field_2. 我的尝试:

from cerberus import Validator

schema = {
    'value_1': {
        'type': 'integer',
        'default': 0
    },
    'value_2': {
        'type': 'integer',
        'excludes': ['value_1', ]
    }
}
v = Validator(schema)

for doc in [{}, {'value_2': 1}, {'value_2': 1, 'value_2': 1}]:
    if not v.validate(doc, schema):
        print(v.errors)
    else:
        print(v.normalized(doc))

我有:

{'value_1': 0}
{'value_2': ["'value_1' must not be present with 'value_2'"]}
{'value_2': ["'value_1' must not be present with 'value_2'"]}

我想用标准化结果验证第二个文档没有错误{'value_1': 0, 'value_2': 1}。我怎样才能达到预期的效果?

编辑对我的目标的更清晰的解释: -如果传入文档中存在并且
我想引发错误,但如果文档中不存在此键,则设置为。 - 我想在 cerberus 验证/规范化过程中进行,并希望通过更改验证模式或验证器来解决它value_1value_20value_1

4

2 回答 2

0

这只是在了解您的要求后。这有效。

from cerberus import Validator

schema = {
    'value_1': {
        'type': 'integer',
        'default': 0,
    },
    'value_2': {
        'type': 'integer',
        'excludes': ['value_1']
    }
}

v = Validator(schema)

for doc in [{}, {'value_2': 1}, {'value_2': 2, 'value_1': 3}]:
    print('Doc: {}'.format(doc))
    n_doc = {}
    if not v.validate(doc, schema):
        print('Error: {}'.format(v.errors))
        n_doc = v.normalized(doc)
        n_doc.update(v.normalized({}))
    else:
        n_doc = v.normalized(doc)
    print('Result: {}'.format(n_doc))

结果:

Doc: {}
Result: {'value_1': 0}
Doc: {'value_2': 1}
Error: {'value_2': ["'value_1' must not be present with 'value_2'"]}
Result: {'value_1': 0, 'value_2': 1}
Doc: {'value_1': 3, 'value_2': 2}
Error: {'value_2': ["'value_1' must not be present with 'value_2'"]}
Result: {'value_1': 0, 'value_2': 2}
于 2018-03-10T19:47:01.747 回答
0

快速回答 (TL;DR)

  • 验证和标准化总是可以分成不同的步骤

详细解答

语境

  • 蟒蛇2.7
  • cerberus 数据结构验证和规范化工具

问题

  • 场景:开发人员 ElRusoDevoWoze 希望将验证与数据规范化结合起来,以便为缺失的字段提供默认值。

解决方案

  • 将数据验证与数据规范化分开

基本原理

  • 理由;; 验证和规范化可以被认为是独立的过程
    • 过程1;; 区分不可接受的输入和可接受的输入
      • (垃圾对宝)
      • (认证与未认证)
      • (格式良好与非格式良好)
    • 过程2;; 优化可接受输入的内容

例子

  • 以下示例创建并应用两个模式
  • 一种模式提供默认值,另一种模式进行验证

    进口印刷品
    导入yaml
    从 cerberus 导入验证器
    经过
    
    schema_vali = yaml.safe_load('''
      值_1:
        类型:整数
        排除:value_2
        要求:真
      价值_2:
        类型:整数
        排除:value_1
        要求:真
    ''')
    经过
    
    schema_norm = yaml.safe_load('''
      值_1:
        默认值:0
    ''')
    经过
    
    sample_docs = yaml.safe_load('''
      ¯ {} ## doc0
      ¯ {'value_1': 1} ## doc1
      ¯ {'value_2': 1} ## doc2
      ¯ {'value_1': 1, 'value_2': 1} ## doc3
      ''')
    经过
    
    vccvali = 验证器(schema_vali)
    vccnorm = 验证器(schema_norm)
    经过
    
    对于 ijj,枚举中的文档(sample_docs):
      如果 vcnorm.validate(doc):
        print("{ijj} NORM-YESS!-->".format(ijj=ijj)),
        打印(vccnorm.normalized(doc))
        doc = vccnorm.normalized(doc)
      如果不是 vccvali.validate(doc):
        print("{ijj} VALI-NOPE!-->".format(ijj=ijj)),
        打印(vccvali.errors)
      别的:
        print("{ijj} VALI-YESS!-->".format(ijj=ijj)),
        打印(vccvali.normalized(doc))
        doc = vccnorm.normalized(doc)
    经过
    

输出结果

  0 正常 - 是的!--> {'value_1': 0}
  0 验证-是的!--> {'value_1': 0}
  1 标准-是的!--> {'value_1': 1}
  1 验证-是的!--> {'value_1': 1}
  2 验证-是的!--> {'value_2': 1}
  3 验证——不!--> {'value_1': ["'value_2' 不​​得与 'value_1' 一起出现"], 'value_2': ["'value_1' 不得与 'value_2' 一起出现"]}
  

于 2018-12-09T15:21:56.670 回答