Fields already provide their own valiation. eg: zope.schema.Int field should be integer, ...
constrains if you need a little more control.
from zope.interface import Invalid def over_21(value): if value >= 21: return True raise Invalid("You need to be over 21, to register.") class IPerson(form.Schema): ... age = schema.Int( title=u"Age", constraint=over_21, required=True)
Validate widget using @form.validator
@form.validator(field=IPerson['age']) def over_21(value): if value >= 21: return True raise Invalid("You need to be over 21, to register.")Possible to make validator more specific or generic using ‘context’, ‘request’, ‘view’, ‘field’, ‘widget’ parameter of @form.validator decorator.
more advanced
from z3c.form import validator class Over21(validator.SimpleFieldValidator): def validate(self, value): # here we could skipt default field validation super(Over21, self).validate(value) if value >= 21: return True raise Invalid("You need to be over 21, to register.") validation.WidgetValidatorDiscriminators(Over21, field=IPerson['age'], view=RegisterForm) grok.global_adapter(Over21)This we use in case:
- want to skip default validation of field properties (‘required’, ‘min’, ..).
- need to access context, request, form, field, widget to validate.
invariants
from zope.interface import invariants class IPerson(form.Schema): ... @invariants def legal_age(data): if data.city == 'Sevilla' and \ data.age >= 18: return True elif data.age >= 21: return True raise Invalid("You need to be over 21, to register.")validation can also happen inside action handler
from z3c.form.interfaces import ActionExecutionError from z3c.form.interfaces import WidgetActionExecutionError class RegisterForm(form.SchemaForm): ... def handleRegister(self, action): data, errors = self.extractData() if data['age'] > 150: raise WidgetActionExecutionError( Invalid(u"nobody should register if its older then 100")) try: registration = getToolByName(self.context, 'portal_registration') registration.addMember(data['email'], '12345', properties=data) except ValueError, e: raise ActionExecutionError( Invalid(u"User with this email already exists.")) if errors: self.status = self.formErorrsMessage return ...
replace only text in error message
from zope.schema.interfaces import ValidationError @form.error_message(field=IPerson['age'], error=ValidationError) def to_young_message(value): return "By the law we are not allowed to let you in. Sorry." \ "See you in %s years." % (21 - value)allowed arguments for error_message are:
error, request, widget, field, form, contet
standard errors are (all listed in zope.schema.interfaces):
RequiredMissing, WrongType, TooBig, TooSmall, TooLong, TooShort, InvalidValue, ConstraintNotSatisfied, WrongContainedType, NotUnique, InvalidURI, InvalidId, InvalidDottedName
output HTML
import zope.component from z3c.form import error from zope.schema.interfaces import TooSmall TooYoung = error.ErrorViewMessage( u'Too young', error=TooSmall, field=IPerson['age']) zope.component.provideAdapter(TooYoung, name='message')