« Getting organised with Turbogears | Main | Authenticating as a portal user in the Zope debugger »

Altering an Archetypes validator after the schema has been defined

To change the validator for a field on an Archetypes schema after the schema has been defined is not as simple as it first looks.

Most values on a schema can be altered simply by reassigning them. If, for example, you wanted to subclass an existing content type so that the default value for a field was different it is fairly obvious that you would need the following schema definition:

However, validators are not so obvious. In the schema definition validators are either strings 'isURL' or tuples ('isEmpty', 'isURL'). To change the validator it would therefore seem sensible to, as above, simply set new_schema['field_to_change'].validators to the required new value, either string or tuple.

Unfortunately this won’t work. You will get an object not callable type error upon submitting your form.

When a field is first defined in a schema the Field.__init__() method is run, and in there the Field._validationLayer() method is called. This method takes the string or tuple that was provided and turns it in to a ValidationChain object. Because of this simply setting my_new_schema['field_name_to_change'].validators to a string or tuple will not work.

Instead it is a two step process. Like you would assume, firstly set the field’s validators property to be the required string or tuple as you would in the schema definition. Then call the field’s _validationLayer() method. This will turn the value that you have provided into a ValidationChain as required.

As an example, suppose I have a schema definition (called BaseEntrySchema) that includes the following field definition:

My customer decides that they would like not only for postcode to be required but also, as they only deal in the UK, to be validated as a UK postcode. Assuming I have written and registered my custom validator isValidUKPostcode instead of re-writing the schema from scratch I can do the following in my type definition:

I now have my new schema, exactly like the original but with the addition of a validator for the postcode field.

Comments

This is really helpfull! I spent hours trying to find out how to solve this. Thank you very much for this tip.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)