Plone - Как я могу заставить валидатор проверять поле из поведения для определенного типа контента?

Я использую 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 в каталогах / default / types) я размещаю поведение в разделе поведения.

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

Проблема состоит в том, что он проверяет конечное поле в любом объекте Event или любом объекте, который реализует интерфейс / схему IEventBasic.

Я подумал, что, возможно, поскольку в документации Plone говорится, что параметры 'view' и 'context' WidgetValueDiscriminators принимают интерфейс, то я мог бы сделать либо:

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 ответ

Решение

Хорошо, зарегистрируйте свою собственную форму добавления и создайте подкласс для формы добавления ловкости по умолчанию. Дополнительная информация о проверке в обработчиках действий и пользовательских формах добавления

в моем task.py (Contenttype и так далее...):

# -*- 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>
Другие вопросы по тегам