4

所以我使用 Cerberus 进行模式验证,但我遇到了一个特殊的问题,即验证一个密钥未知的字典的子字典。

所以说我有以下文件:

dict = {
   'things': {
       '0463': {
           'foo': 'blah',
           'bar': 'bleep'
        },
        '0464': {
           'foo': 'x',
           'bar': 'y'
        },
        'another_random_id': {
           'foo': 'blah',
           'bar': 'bleep'
        }
}

所以我想验证子词典是否具有特定的结构(foobar作为键),但我无法在不提前知道键的情况下找到一种方法来验证它(在我的情况下是随机 id。我想这是很好地使用了 valueschema 但我似乎无法让 valueschema 与“dict”类型的东西一起工作。我试图在 cerberus 中设置以下模式:

schema = {
    'things': {
        'type': 'dict',
        'valueschema': {
             'type': 'dict',
             'foo': {'type': 'string'},
             'bar': {'type': 'string'}
         }
     }
}

我是否错误地定义了我的架构,或者这对于当前的valueschema. 我在存储库中看到了一些使用 的测试valueschema,但它们只测试类型valueschema是 int 或 string 的情况。

4

1 回答 1

4

因此,我发现如果我在键后放置一个字段,那么 cerberus 将处理valueschema它的类型。所以我的结构应该是:dictschemavalueschema

schema = {
    'things': {
        'type': 'dict',
        'valueschema': {
             'type': 'dict',
             'schema':{
                 'foo': {'type': 'string'},
                 'bar': {'type': 'string'}
             }
         }
     }
}

现在仍然有一些奇怪之处,因为它看起来不像valueschema是在设计时期望它会验证 type 的值dict。例如,当我从验证器扩展时,我必须重写该validate_valueschema方法,以便required验证的行为与常规模式相同,因为当它调用validate模式时,它不会传入update参数。所以我的覆盖validate_valueschema看起来像这样:

def _validate_valueschema(self, schema, field, value):
    if isinstance(value, Mapping):
        for key, document in value.items():
            validator = self._Validator__get_child_validator()
            validator.validate(
                {key: document}, {key: schema}, 
                context=self.document, update=self.update)
            if len(validator.errors):
                self._error(field, validator.errors)

update=self.update就是我添加的所有内容。

于 2016-06-08T15:20:41.927 回答