Python Cerberus 如何检查动态根 key

标签 python python-3.x validation cerberus

我有一个以 ID 作为根键的字典,我想验证它。换句话说,我想要验证的字典的根键是动态的。有没有办法针对根 key 运行 key 架构?

例如https://repl.it/@crunk1/cerberusrootkeys

import cerberus

v = cerberus.validator.Validator()
schema = {'keyschema': {'type': 'string'}}
d = {'foo': 'bar', 'baz': 'gaz'}

print('I want this to be true.')
print(v.validate(d, schema))

### Output:
# I want this to be true.
# False

我知道我可以执行以下操作:

wrapper = {'nested': d}
schema = {'nested': {'keyschema': {'type': 'string'}}}
v.validate(wrapper, schema)

但我的项目的当前结构不容易允许这样做。

有什么解决方案/提示/建议吗?

最佳答案

我设法一起破解一些东西( https://repl.it/@crunk1/Cerberus-root-types )子类化 Validator 并重写 validate():

class V(cerberus.Validator):
  def validate(self, document, schema=None, update=False, normalize=True):
    doc = None
    wrapped = False
    if schema is not None:
      root_schema = schema.get('__root__', None)
      wrapped = root_schema is not None
      if wrapped:
        doc = {'__root__': document}
        schema = {'__root__': root_schema}
    elif self.schema is not None:
        root_schema = self.schema.get('__root__', None)
        wrapped = root_schema is not None
        if wrapped:
            doc = {'__root__': document}
            schema = {'__root__': root_schema}

    doc = doc or document
    result = super(V, self).validate(doc, schema, update, normalize)
    if wrapped:
      # Unwrap.
      self.document = self.document['__root__']
      for e in self._errors:
        e.schema_path = tuple(e.schema_path[1:])
        if len(e.document_path) > 1:
          e.document_path = tuple(e.document_path[1:])
    return result

这允许您将根文档视为 'type': 'dict''type': 'list'

v = V()
d = {'1': '1', '2': '2'}
schema = {'__root__': {
  'type': 'dict',
  'keyschema': {'coerce': int},
  'valueschema': {'coerce': int},
}}
print(v.validate(d, schema), v.document, v.errors)

l = ['1', '2']
schema = {'__root__': {
  'type': 'list',
  'schema': {'coerce': int},
}}
print(v.validate(l, schema), v.document, v.errors)

l = ['1', 'b']
print(v.validate(l, schema), v.document, v.errors)

输出:

True {1: 1, 2: 2} {}
True [1, 2] {}
False [1, 'b'] {1: ["field '1' cannot be coerced: invalid literal for int() with base 10: 'b'"]}

关于Python Cerberus 如何检查动态根 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49762642/

相关文章:

python - 在 Python 中从字符串中提取数字

php - Yii - ajax 加载表单元素的用户端验证

python - 用 `$` 替换第一个字符的所有后续出现

python - 如何让 Selenium WebDriver 等到 <dd> 元素包含数据后再继续?

python - 即使节点位于 networkx 图中,使用 pygraphviz_layout 时也会出现 "KeyError: Node not in graph"

javascript - 使用 laravel 4.2 和 jQuery 进行动态文件上传和验证

javascript - 使用 jquery validate 验证具有相同类的多个表单

javascript - 导入 .js 文件并使用其中的定义

python - 通过python计算文本文件中的单词

windows - 为什么对象的 id 会根据 python shell 中的行而改变