Plone - 如何使验证器根据特定内容类型的行为验证字段?

时间:2016-10-25 12:05:10

标签: validation plone z3c.form zope.interface

我正在使用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)

在我的类型文件(profiles / default / types下的my.object.myobject.xml)中,我将行为放在了行为部分。

<behaviors>
    <element value="plone.app.event.dx.behaviors.IEventBasic"/>
</behaviors>

问题是它验证了任何Event对象中的end字段或实现IEventBasic接口/ schema的任何对象。

我想也许是因为Plone文档说WidgetValueDiscriminators的参数'view'和'context'接受了一个接口,然后我可以这样做:

validator.WidgetValidatorDiscriminators(EndMyObjectValidator, view=IMyObject, field=IEventBasic['end'])

validator.WidgetValidatorDiscriminators(EndMyObjectValidator, context=IMyObject,field=IEventBasic['end']

不幸的是,这些都没有触发。我想我误解了上下文和视图参数实际上做了什么。 我怎样才能使验证器专门用于处理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: 之前我删除了我的评论,因为这是一个无关的问题。 我改变了检查类型的方式。

1 个答案:

答案 0 :(得分:3)

好的,注册你自己的添加表格和子类化默认敏捷添加表格。有关Validating in action handlersCustom Add Forms

的更多信息

在我的String(内容类型等等)中:

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

在我的task.xml中定义:

<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>