[Grok-dev] Question re EditForm and ZPT

Martijn Faassen faassen at startifact.com
Mon Nov 23 04:55:03 EST 2009


Kathy Manwaring wrote:
> I have created a ZPT which has the following button present:
> <input type="submit" id="SubmitButton" name="SubmitButton" value="Save"
> class="button" />
> 
> The relevant class has an update method that is triggered by the button:
> class Edit(grok.EditForm):
>     grok.context(Person)
>     template = grok.PageTemplateFile('people_templates/edit.pt')
> 
>     def update(self, SubmitButton=None, **data):
>         # Check if the submit button was clicked.
>         if SubmitButton == None:
>             print 'SubmitButton empty'
>         if SubmitButton != None:
>             print 'SubmitButton is:' + SubmitButton + ':'
>         if SubmitButton == 'Save':
>             print 'you hit the Save button'
>             # copy the new or updated information
>             print self.context
>             print self
>             self.applyData(self.context, **data)
>             print 'have set fields'
> 
> Error: AttributeError: 'Edit' object has no attribute 'adapters'

[snip]

> As this is just a button, and it's defined based on EditForm, why does
> applyData give an error?
> 
> Hoping someone can help, as this really has me stumped - all the
> documentation says that I've done it right...

It's definitely a strange error.

I see a few unusual things:

You have manually set your page template using 'template'. You ought to 
be able to just leave the 'template' line out entirely and things should 
still work. I don't see how this would be the cause of your problem, 
however.

You haven't set form_fields. Normally if you use grok.EditForm you'd use 
Grok's form system and you'd need to set form_fields using grok.Fields().

Finally, you try to handle a grok.EditForm during an 'update()'. When 
you use grok.EditForm, you'll have to use all of it: generating form 
fields from a schema, and validating the information using handlers that 
say @grok.action(). Instead you try to handle the input manually and try 
to do 'applyData' with information that's in your raw form.

You have two choices:

* stick with a hand-generated form but use a grok.View, not 
grok.EditForm. The only bit you have missing would be 'applyData'. If 
you are certain that you can simply put the fields on the contexts 
without any further validation, you can easily implement applyData yourself:

def myApplyData(obj, **data):
     for key, value in data.items():
          setattr(obj, key, value)

* actually use Grok's high-level form machinery, including a schema and 
form_fields and so on. For more information about that you can read the 
developer's notes:

http://grok.zope.org/doc/current/grok_overview.html#forms

This also contains a bunch of tutorials:

http://grok.zope.org/documentation/phc_topic_area?topic=Forms

Note that at least the second tutorial "Automatic Form Generation" 
currently has a problem as it depends on a library called z3c.widget 
which won't install properly.

Briefly, you'd not implement your own 'update', you'd define a 
form_fields and you'd use @grok.action() to define the submit button 
handler.

Good luck!

Martijn



More information about the Grok-dev mailing list