[Grok-dev] applyChanges and add forms

Martijn Faassen faassen at startifact.com
Fri Apr 13 09:48:47 EDT 2007


Hi there,

Philipp did a refactoring of the form structure a while ago, and one of 
the things he did was make applyChanges useable in add forms. But I ran 
into a snag that might give us insight in what applyChanges should 
really be doing for us in the context of grok.AddForm.

I created a simple content class that just claims it implements a 
schema. Then I expected to be able to do the following:

class IMyContent(Interface):
     line = schema.TextLine(title=u'Line')

class MyContent(grok.Model):
     implements(IMyContent)

class AddForm(grok.AddForm):
     grok.context(IContainer)

     form_fields = grok.Fields(IMyContent)

     @grok.action('Save')
     def handle_add(self, **kw):
         obj = MyContent()
         self.applyChanges(obj, **kw)
         self.context['test'] = obj

Unfortunately I instead got this exception:

   File "/home/faassen/buildout/IngForms/grok/src/grok/components.py", 
line 411, in applyChanges
     if form.applyChanges(obj, self.form_fields, data, self.adapters):
   File 
"/home/faassen/buildout/Zope-3.3.1/build/lib.linux-i686-2.4/zope/formlib/form.py", 
line 526, in applyChanges
     if (newvalue is not form_field) and (field.get(adapter) != newvalue):
   File 
"/home/faassen/buildout/Zope-3.3.1/build/lib.linux-i686-2.4/zope/schema/_bootstrapfields.py", 
line 171, in get
     return getattr(object, self.__name__)

This is because applyChanges in formlib tries to retrieve the data from 
the content object before it saves. This is to determine whether to 
actually change the field at all, and to set a 'changed' flag that's 
returned - if the underlying content object already has these values, no 
changes happen and nothing needs to be done.

This is nice in case of edit forms, but it blocks this usage of 
AddForms. Of course, in fact I lied in the above code. I claimed that 
MyContent implements the schema IMyContent but I do no such thing. I 
intuitively expected applyChanges help me make sure that this happened, 
but perhaps this is not the right pattern.

What can be do to make schema-driven content even simpler in Grok? 
Having to do a special __init__ and typing all the fields again seems a 
bother I'd like to avoid.

Regards,

Martijn




More information about the Grok-dev mailing list