Plone - 如何让验证器根据特定内容类型的行为验证字段?
Plone - How can I make a validator validate a field from a behavior for a specific content type?
我正在使用 Plone 4.3,我有一个 form.SchemaForm plone.directives 有一个接口,该接口有一个来自 IEventBasic 的起始字段和一个验证器:
from datetime import timedelta
from plone.directives import form
from plone.app.contenttypes.interfaces import IEvent
from z3c.form import validator
from zope.component import provideAdapter
from zope.interface import Invalid
class IMyObject(form.SchemaForm)
my_field_a = schema.TextLine(title='a_field')
...
class MyObject(Item):
implements(IMyObject, IEvent)
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
#code for checking if end field is within a certain range from start field
if self.end > self.start + timedelta(days=6):
raise Invalid('The end date is not within range of the start date's week')
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
在我的类型文件中(my.object.myobject.xml 在 profiles/default/types 下),我将行为放在行为部分。
<behaviors>
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</behaviors>
问题是它验证任何事件对象或任何实现 IEventBasic 的对象中的结束字段 interface/schema。
我想也许因为 Plone 文档说 WidgetValueDiscriminators 的参数 'view' 和 'context' 接受一个接口,那么我可以这样做:
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, view=IMyObject, field=IEventBasic['end'])
或
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, context=IMyObject,field=IEventBasic['end']
不幸的是,none 根本不会触发。我想我误解了上下文和视图参数的实际作用。
我怎样才能使验证器专门用于处理 MyObject?
来源:http://docs.plone.org/develop/addons/schema-driven-forms/customising-form-behaviour/validation.html
目前我在做:
...
from gpcl.container.my_container import MyContainer
...
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
if self.widgets.form.portal_type <> 'my.object.myobject':
return
...
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
更新 2:
我之前删除了我的评论,因为它是针对一个不相关的问题。
我改变了检查类型的方式。
好的,注册您自己的添加表单并将默认敏捷添加表单子类化。有关 Validating in action handlers and Custom Add Forms
的更多信息
在我的task.py
(内容类型等等......):
# -*- coding: utf-8 -*-
from zope.interface import implementer
from zope.interface import Invalid
from z3c.form import button
from z3c.form import validator
from z3c.form import util
from z3c.form.interfaces import ActionExecutionError
from z3c.form.interfaces import WidgetActionExecutionError
from plone.dexterity.content import Item
from plone.dexterity.browser import add
from viisionar.training.interfaces import ITask
from Products.statusmessages.interfaces import IStatusMessage
from my.addon import _
@implementer(ITask)
class Task(Item):
pass
class AddForm(add.DefaultAddForm):
portal_type = 'Task'
def __init__(self, context, request, ti=None):
super(AddForm, self).__init__(context, request, ti=None)
@button.buttonAndHandler(_('Save'), name='save')
def handleAdd(self, action):
print "Handle Add"
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
# Your Custom validation
# Debug Do what yo want
print data
if error:
"""
# Global Portal Message
raise ActionExecutionError(Invalid(_(u"Please provide a valid end date")))
# or
# Error Message in Widget
raise WidgetActionExecutionError('IEventBasic.end', Invalid(u"Please put the the right end date"))
"""
# /Your Custom validation
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True
IStatusMessage(self.request).addStatusMessage(
self.success_message, "info"
)
class AddView(add.DefaultAddView):
form = AddForm
在我的 configure.zcml
中,我注册了自定义添加表单
<adapter
for="
Products.CMFCore.interfaces.IFolderish
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.dexterity.interfaces.IDexterityFTI"
provides="zope.publisher.interfaces.browser.IBrowserPage"
factory="my.addon.task.AddView"
name="Task" />
<class class="my.addon.task.AddView">
<require
permission="cmf.AddPortalContent"
interface="zope.publisher.interfaces.browser.IBrowserPage"/>
</class>
在我的 task.xml 定义中:
<property name="factory">Task</property>
<property name="schema">my.addon.interfaces.ITask</property>
<property name="klass">my.addon.task.Task</property>
<property name="behaviors">
<element value="plone.app.content.interfaces.INameFromTitle" />
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</property>
我正在使用 Plone 4.3,我有一个 form.SchemaForm plone.directives 有一个接口,该接口有一个来自 IEventBasic 的起始字段和一个验证器:
from datetime import timedelta
from plone.directives import form
from plone.app.contenttypes.interfaces import IEvent
from z3c.form import validator
from zope.component import provideAdapter
from zope.interface import Invalid
class IMyObject(form.SchemaForm)
my_field_a = schema.TextLine(title='a_field')
...
class MyObject(Item):
implements(IMyObject, IEvent)
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
#code for checking if end field is within a certain range from start field
if self.end > self.start + timedelta(days=6):
raise Invalid('The end date is not within range of the start date's week')
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
在我的类型文件中(my.object.myobject.xml 在 profiles/default/types 下),我将行为放在行为部分。
<behaviors>
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</behaviors>
问题是它验证任何事件对象或任何实现 IEventBasic 的对象中的结束字段 interface/schema。
我想也许因为 Plone 文档说 WidgetValueDiscriminators 的参数 'view' 和 'context' 接受一个接口,那么我可以这样做:
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, view=IMyObject, field=IEventBasic['end'])
或
validator.WidgetValidatorDiscriminators(EndMyObjectValidator, context=IMyObject,field=IEventBasic['end']
不幸的是,none 根本不会触发。我想我误解了上下文和视图参数的实际作用。 我怎样才能使验证器专门用于处理 MyObject?
来源:http://docs.plone.org/develop/addons/schema-driven-forms/customising-form-behaviour/validation.html
目前我在做:
...
from gpcl.container.my_container import MyContainer
...
class EndMyObjectValidator(validator.SimpleFieldValidator):
def validate(self,value):
if self.widgets.form.portal_type <> 'my.object.myobject':
return
...
validator.WidgetValueDiscriminators(EndMyObjectValidator, field=IEventBasic['end'])
provideAdapter(EndMyObjectValidator)
更新 2: 我之前删除了我的评论,因为它是针对一个不相关的问题。 我改变了检查类型的方式。
好的,注册您自己的添加表单并将默认敏捷添加表单子类化。有关 Validating in action handlers and Custom Add Forms
的更多信息在我的task.py
(内容类型等等......):
# -*- coding: utf-8 -*-
from zope.interface import implementer
from zope.interface import Invalid
from z3c.form import button
from z3c.form import validator
from z3c.form import util
from z3c.form.interfaces import ActionExecutionError
from z3c.form.interfaces import WidgetActionExecutionError
from plone.dexterity.content import Item
from plone.dexterity.browser import add
from viisionar.training.interfaces import ITask
from Products.statusmessages.interfaces import IStatusMessage
from my.addon import _
@implementer(ITask)
class Task(Item):
pass
class AddForm(add.DefaultAddForm):
portal_type = 'Task'
def __init__(self, context, request, ti=None):
super(AddForm, self).__init__(context, request, ti=None)
@button.buttonAndHandler(_('Save'), name='save')
def handleAdd(self, action):
print "Handle Add"
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
# Your Custom validation
# Debug Do what yo want
print data
if error:
"""
# Global Portal Message
raise ActionExecutionError(Invalid(_(u"Please provide a valid end date")))
# or
# Error Message in Widget
raise WidgetActionExecutionError('IEventBasic.end', Invalid(u"Please put the the right end date"))
"""
# /Your Custom validation
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True
IStatusMessage(self.request).addStatusMessage(
self.success_message, "info"
)
class AddView(add.DefaultAddView):
form = AddForm
在我的 configure.zcml
中,我注册了自定义添加表单
<adapter
for="
Products.CMFCore.interfaces.IFolderish
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.dexterity.interfaces.IDexterityFTI"
provides="zope.publisher.interfaces.browser.IBrowserPage"
factory="my.addon.task.AddView"
name="Task" />
<class class="my.addon.task.AddView">
<require
permission="cmf.AddPortalContent"
interface="zope.publisher.interfaces.browser.IBrowserPage"/>
</class>
在我的 task.xml 定义中:
<property name="factory">Task</property>
<property name="schema">my.addon.interfaces.ITask</property>
<property name="klass">my.addon.task.Task</property>
<property name="behaviors">
<element value="plone.app.content.interfaces.INameFromTitle" />
<element value="plone.app.event.dx.behaviors.IEventBasic"/>
</property>