> I've done interface constraints before and raised ValidationErrors.
> However, in this case that won't work because the error can only occur
> during the action handler (and without access to the request, which
> carries a particular foreign key, I can't look in the database to
> predict whether it would fail).
> Is there some way of doing this?
Unfortunatelly formlib seems to be concerned mainly on ZODB.
But it is possible to do validation on success handler level.
Darryl Cousins already asked about this on zope3-users and
I suggested to use something like:

Function defined in view class eg. descendant of EditForm:

     from zope.app.form.interfaces import WidgetInputError

     def setWidgetError(self, name, v):
         """ Helper function for validation purposes.
             Sets error for widget
              @name - field name
              @v - error message
         w = self.widgets.get(name)
         if w:
             w._error = WidgetInputError(
               self.context.__name__, w.label, v)
         return w._error

In function used as success handler I did:

 if not data['myfield']:   # some errors from rdbms with myfield etc.
     error = self.setWidgetError('myfield',
                                 'value can\'t be above a number N')

     # it is necessary to manually handle form reset here
     self.form_reset = False

AFAIK it may be also necessary to set self.status to have error messages

There is also another thing you may do.
If you take a look at 'update' method of FormBase in form.py
then you can see that success handler method is not even supposed to
return any errors but it is easy to change this behaviour. For example
I changed my 'update' method to this:

        if errors:
            self.status = _('There were errors')
            result = action.failure(data, errors)
        elif errors is not None:
            result = action.success(data)
            if not self.errors:
                self.form_reset = True
                self.status = _('There were errors')
                result = action.failure(data, errors)
            result = None

this way you only have to set self.errors in your success handler
function. status and form_reset are handled 'automatically'

Maciej Wisniowski

Zope3-users mailing list

Reply via email to