以编程方式创建 Dexterity 类型时,是否可以验证传递给工厂的数据,就好像它来自表单一样?
我有一个带有许多约束、不变量和验证器的 Dexterity 内容类型:
from zope import schema
from zope import interface
from z3c.form import validator
from plone import dexterity
from plone.directives import form
from five import grok
def is_not_foo(value):
return value is not 'foo'
class IMyType(form.Schema):
my_value = schema.TextLine(
constraint = is_not_foo
)
min = schema.Int(default=0)
max = schema.Int(default=99)
@interface.invariant
def max_more_than_min(data):
if data.min is not None and data.max is not None:
if data.min >= data.max:
raise interface.Invalid( u'Min is more than Max' )
@form.error_message(form=IMyType['my_value'], error=schema.interfaces.ConstraintNotSatisfied)
def error_my_value_is_foo(value):
return u'my_value must not be "foo"'
class ValidateMyValue(validator.SimpleFieldValidator):
def validate(self, value):
if value is not None:
# value passes some test
validator.WidgetValidatorDiscriminators(
ValidateMyValue,
form = IMyType['my_value'],
)
grok.global_adapter(ValidateMyValue)
为了确保 MyType 的所有实例都具有正确的默认值,我为它创建了一个自定义类,其属性使用 FieldProperty 映射,并在类型的 FTI 声明中分配它:
class MyType(dexterity.content.Item):
interface.implements(IMyType)
my_value = schema.fieldproperty.FieldProperty(IMyType['my_value'])
min = schema.fieldproperty.FieldProperty(IMyType['min'])
max = schema.fieldproperty.FieldProperty(IMyType['max'])
但是,使用 时plone.dexterity.utils.createContentInContainer
,可能会实例化不符合所施加的约束等的对象。理想情况下,我希望能够在创建之前自己执行此验证。
我在这里缺少一种简单的方法吗?我已经简要查看了collective.transmogrifier,但我没有看到输入验证的提及。
谢谢。