[TransWarp] Constraints on model attributes

Roché Compaan roche at upfrontsystems.co.za
Sat Jul 26 18:01:26 EDT 2003

* Phillip J. Eby <pje at telecommunity.com> [2003-07-26 21:46]:
> At 06:43 PM 7/26/03 +0200, Roché Compaan wrote:
> >How does one define constraints for model attributes? Last time you talked
> >about this was back in January.
> If you have a mdl_normalize() method on a feature's  'referencedType', it 
> is called with any value assigned to the feature (or added, if the feature 
> is a collection).  You can also define cardinality via a feature's 
> lowerBound and upperBound attributes.
> Currently, to get any validation apart from cardinality and type 
> constraints, you have to define _onLink()/_onUnlink() methods, which are 
> also called when changes are made to a feature.

This isn't very intuitive but will do the job. It would be nice though
if constraints are made more obvious in a class definition eg.:

    class Person(model.Element):

        class Age(model.Attribute):
            referencedType = model.Integer
            constraint = lambda i: i < 100 # this can be any function
            required = True
            default = 0

Are type constraints actually enforced, because I just created a very simple
class with a model.Attribute with referencedType set to model.String and
no exception was raised when I assigned an integer to it. Mmm, it seems
you have to define normalize:

    def mdl_normalize(value):
        """Return 'value' normalized to the type, or raise error if invalid

        If a type does not supply this method, features using the type
        will accept any value."""

If this is the case then I will have to subclass most types to enforce
type constraints.

You might be interested to look at Zope3/src/zope/schema/interfaces.py,
specifically the constraint and validate methods.

> >I am very impressed by Zope 3's schema support and the ability to
> >generate web forms based on the schema - you can imagine that it saves a
> >lot of repetitive template coding. I think it is possible to do the same
> >with PEAK the only difference being that one will generate forms using
> >PEAK's model semantics.
> As you might notice, a fair amount of PEAK's model system was designed with 
> that in mind.  Things like 'mdl_features' on model.Type classes, so you can 
> easily iterate over a class' feature metadata.  You can also define the 
> sorting order of features.

Yes, this kind of introspection will help a lot when generating forms.

> The one thing that I didn't really think about was that you can't 
> necessarily select what type of form widget should be used for something, 
> based solely on the data types.

Well, you can't ;-) The idea is to provide default widgets for
datatypes. Customisation of generated forms must definitely possible.

> >I am very familiar with Formulator and the form generation code in Zope
> >3 and it would be rather trivial to implement something like it for
> >PEAK.
> That's good to hear; I've been worried about that.

How so?

> >Being able to define constraints for attributes on a model element
> >is required to validate form values.
> Look at the methods that feature objects have, especially toString(), 
> fromString(), and normalize().  If you run into any issues, let me know, 
> and I'll see what I can do to strengthen up the framework.

The normalize function will be most helpful for what I want to do but it
feels funny to define 'normalize' on a feature when I actually want to
'validate'. What is the background to 'normalize'?

Roché Compaan
Upfront Systems                 http://www.upfrontsystems.co.za

More information about the PEAK mailing list