В общем случае валидаторы схемы стараются избегать ввода данных в валидатор.Например, стандарт JSON-схемы - это , обсуждающий добавление $data
доступа в схемах , но (пока) не реализовавший эту идею (хотя они несколько используютслучаи для этого ).
Общее возражение состоит в том, что из-за того, что привязка схемы проверки к проверяемым данным затрудняет проверку без контекста (что упрощает реализацию и делает проверку параллельно)намного проще), и это делает статический анализ схем намного сложнее (так как схема изменяется с данными во время выполнения).
Тем не менее, проект Colander может делать то, что вы хотите,поскольку это позволяет вам тривиально определять валидаторы в коде Python.
Например:
import colander
class Foo(colander.MappingSchema):
@colander.instantiate()
class notions(colander.SequenceSchema):
notion = colander.SchemaNode(colander.String())
@colander.instantiate()
class category(colander.SequenceSchema):
cat = colander.SchemaNode(colander.String())
def validator(self, node, cstruct):
"""Validate that all category values are listed in notions"""
notions = set(cstruct['notions'])
if not notions.issuperset(cstruct['category']):
raise colander.Invalid(
node['category'],
"All categories must be listed in notions"
)
Обратите внимание, что валидатор определен на уровне, где определены и notions
, и category
в, поскольку валидатор имеет доступ только к «локальному» разделу проверяемых данных (все проверки дочерних узлов уже проведены).Если вы определили валидатор только для category
, то вы не сможете получить доступ к списку notions
, и вы можете рассчитывать на список notions
, который уже был проверен.Валидатор вызывает исключение Invalid
, и первым аргументом является узел схемы category
, который прямо возлагает вину на значения в этом списке.
Схема Коландера проверяется при десериализации;Вы можете увидеть ввод метода Schema.deserialize()
в виде непроверенных данных ( сериализация дуршлаг ) и вывод в виде данных, готовых для приложения ( appdata ), проверенных и очищенных.Это потому, что Colander также поместит значения по умолчанию на место, если они отсутствуют, может создавать кортежи, наборы, значения datetime
и т. Д., А также поддерживает подготовку данных (очистку HTML и т. Д.) При обработке их со схемой.
С некоторым демонстрационным вводом приведенная выше схема проверяет и возвращает проверенную структуру в случае успеха:
>>> schema = Foo()
>>> schema.deserialize({'notions': [], 'category': []})
{'notions': [], 'category': []}
>>> schema.deserialize({'notions': ['foo', 'bar'], 'category': []})
{'notions': ['foo', 'bar'], 'category': []}
>>> schema.deserialize({'notions': ['foo', 'bar'], 'category': ['foo']})
{'notions': ['foo', 'bar'], 'category': ['foo']}
>>> schema.deserialize({'notions': ['foo', 'bar'], 'category': ['foo', 'spam']})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/.../site-packages/colander/__init__.py", line 2381, in deserialize
self.validator(self, appstruct)
File "<string>", line 17, in validator
colander.Invalid: {'category': 'All categories must be listed in notions'}