Hello,
On Mon, Jan 22, 2007 at 05:03:43PM +0100, Alex Furlong wrote:
i have some problems with creating a custom edit form. Here is my complete
test code:
from zope.formlib import form
from zope.publisher.browser import TestRequest
class MyEdit(form.EditForm):
def __init__(self, context, request):
self.context = context
self.request = request
import pdb;pdb.set_trace() # set debugger break point
action = form.Action('Edit', success='handle_edit_action')
Ah, this is going to be fun :)
self.actions = form.Actions(action)
def test():
request = TestRequest()
obj = object()
myform = MyEdit(obj, request)
If i use this code in Zope then i get an error like this: Action
object does not have an attribute 'form' .
*nod*
So my first question is, where does the 'form' attribute come from?
Magic.
Do you know how methods work in Python? You assign a function to a
class attribute, and when you access that attribute on an instance of
the class, you get back a bound method. The bound method knows which
instance you used -- that's why it's called a bound method.
Under the hood this is implemented using descriptors. A descriptor is
an object that has a special __get__ method. When the value of a class
attribute is a descriptor, and you access that attribute on an instance,
the descriptor's __get__ gets called and return the value that you'll
get.
The __get__ of an unbound method will create a bound method object.
Likewise, the formlib's form.Action class has a __get__ method that
returns a copy of the action, with the 'form' attribute set.
This mechanism only works when you assign descriptors to class
attributes. It does not work when you assign descriptors to object
attributes, or local variables, like you did.
The simplest way to fix your problem is to bind the actions manually:
def __init__(self, context, request):
self.context = context
self.request = request
action = form.Action('Edit', success='handle_edit_action')
action = action.__get__(self)
self.actions = form.Actions(action)
Or you can do it all in one go
def __init__(self, context, request):
self.context = context
self.request = request
action1 = form.Action('Edit', success='handle_edit_action')
action2 = form.Action('Edit Again', success='handle_edit_action')
actions = form.Actions(action1, action2)
self.actions = form.Actions(actions).__get__(self)
I do not know whether there are cleaner solutions. (I always feel a bit
dirty when I call a method that starts with an underscore on an object
other than 'self'.)
HTH,
Marius Gedminas
--
TCP_UP - The 16-bit TCP Urgent Pointer, encoded as the hex
representation of the value of the field. The hex string MUST be
capitalized since it is urgent.
-- RFC 3093
signature.asc
Description: Digital signature
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users