In my TG CRUD work, I generate edit form, view list and view screen
from SQLObject. I use the similar approach of Kevin : using *arg or a
list in the contrustor of a CompositeWidget. I also add an append()
method. Advantages of this solution :
* easy to create and extends a form automaticaly
...
    editWidgetMap = {
        'container' : widget4edit.FormWidgetsList,
        'default' : widget4edit.TextLineWidget,
        'SOStringCol': widget4edit.TextLineWidget,
        'SOStringCol+long': widget4edit.TextWidget,
        'SOUnicodeCol': widget4edit.TextLineWidget,
        'SOUnicodeCol+long': widget4edit.TextWidget,
        'SOBoolCol': widget4edit.CheckBoxWidget,
        'SOForeignKey' : widget4edit.VocabularyWidget,
        'SOEnumCol' : widget4edit.VocabularyWidget,
#        'SOIntCol':IntWidget,
#        'SODateTimeCol':DateTimeWidget
    }


    def buildWidgetsList(self, sqlobj, widgetmap):
        """
        @param sqlobj the type (like app.model.Page) for wich create a
WidgetContainer
        @param widgetmap the family of widgets to use for each
SQLObject field type
        """
        back = []
        columns = sqlobj.sqlmeta.columns
        for col in sqlobj.sqlmeta.columnList:
            name = col.origName
            clazz = col.__class__.__name__
            if (clazz == 'SOStringCol' or clazz == 'SOUnicodeCol') and
not(col.length):
                clazz += '+long'
            widget = widgetmap.get(clazz,
widgetmap['default'])(key=name)
            if hasattr(widget, 'vocabulary') and (widget.vocabulary is
None):
                if clazz == 'SOForeignKey':
                    referencedsql = findClass(col.foreignKey)
                    widget.vocabulary = SQLVocabulary(referencedsql)
                elif clazz == 'SOEnumCol':
                    widget.vocabulary =
widgetsupport.Vocabulary(col.enumValues)
                    if hasattr(widget, 'defaultValue') and
(widget.defaultValue is None):
                        widget.defaultValue = col.enumValues[0]
            if hasattr(widget, 'required') and (widget.required is
None):
                widget.required = col.notNone
            if hasattr(widget, 'validator') and (widget.validator is
None):
                widget.validator = col.validator
            back.append(widget)
        return widgetmap['container'](*back) #IGNORE:W0142
...

* the WidgetContainer instance could be attach to a SQLObject type. In
my case after building a WidgetContainer I do :
        if not(hasattr(sqlobj, 'editWidget')):
            #autogeneration of the editwidget
            sqlobj.editWidget = self.buildWidgetsList(sqlobj,
self.editWidgetMap)
            sqlobj.editWidget.append(widget4edit.HiddenWidget('isNew',
validators.Bool(), True))
            sqlobj.editWidget.append(widget4edit.HiddenWidget('id',
validators.Int(), -1))

* you could create 2 instances of the same WidgetContainer, an each one
could have it's own internal state without interference, like 2
instances of TextField... (may be my java background influence me too
much, but class state/field are share by all instance, and there is
only one class definition available in the system)

my 2 cents

Reply via email to