[Zope3-Users] object widgets, persistency

Andreas Reuleaux reuleaux at web.de
Mon Apr 25 17:42:25 EDT 2005


Roger Ineichen was so kind to answer my questions about object
widgets (I had contacted him privately as I was not on this list yet.) 
Basically I tried to get his mother/father/family example at
/Zope3/src/zope/app/form/browser/objectwidget.txt to work. - Besides
mother and father I added two simple TextLine attributes foo and bar
to family.

The solution I have now works fine and is shown below (everything is
in a package families). I think it is nice in that one can rely on
automatically have the machinery generated the code for the widgets,
even the object widgets. Only very few things have to be hand-written:
Especially I learned how to write the FamilyEditView class and how to
use it in the configuration with class=".fview.FamilyEditView" (the
problems I had were my zope 3 beginner faults).

Then I tried to make Family persistent, i. e. 

    from persistent import Persistent
    class Family(Persistent):
      ...

and I learned subobjects should be persistent, too

    from persistent import Persistent
    class Person(Persistent)
      ...

Now when I change family objects in the editform I can do so safely
with foo and bar, but changing Mother's or Father's name results in an
error:

    UnpickleableError: Cannot pickle <type 'zope.security._proxy._Proxy'> objects

The complete error log is shown below, too. - It seems to me that
because one has to declare view- (rs. edit-) permissions for Person

    <require permission="zope.View"
      interface=".iperson.IPerson"
    />

Person is wrapped in a security proxy and therefore family can't be
saved (pickeled) any more. - Any idea how to solve this?

I don't have this problem if I only make Person persistent (not
Family) but of course then I am losing changes to the family
attributes foo and bar.

Andreas


--------------------------------------------------
iperson.py
--------------------------------------------------
from zope.interface import Interface
from zope.schema import TextLine

class IPerson(Interface):
    """A Person.
    """

    name = TextLine(
        title=u"Name",
        description=u"Name of the Person.",
        required = False
        )



--------------------------------------------------
person.py
--------------------------------------------------
from zope.interface import implements
from iperson import IPerson
from zope.schema.fieldproperty import FieldProperty

class Person(object):
    """A Person."""

    implements(IPerson)
    
    name = FieldProperty(IPerson['name'])
    
    def __init__(self,
                 name=u''):
        self.name=name



--------------------------------------------------
ifamily.py
--------------------------------------------------
from zope.interface import Interface
from zope.schema import Object, TextLine
from iperson import IPerson

class IFamily(Interface):
    """A Family
    """
    
    mother=Object(title=u"Mother",
                  required = False,
                  schema=IPerson)
    father=Object(title=u"Father",
                  required = False,
                  schema=IPerson)
    foo = TextLine(title=u"Foo",
                   description=u"...",
                   required = False)
    bar = TextLine(title=u"Bar",
                   description=u"...",
                   required = False)


--------------------------------------------------
family.py
--------------------------------------------------
from zope.interface import implements
from ifamily import IFamily
from zope.schema.fieldproperty import FieldProperty

class Family(object):
    """A Family."""
    
    implements(IFamily)

    mother = FieldProperty(IFamily['mother'])
    father = FieldProperty(IFamily['father'])
    foo = FieldProperty(IFamily['foo'])
    bar = FieldProperty(IFamily['bar'])

    def __init__(self,
                 mother=None,
                 father=None,
                 foo=u'',
                 bar=u''):
        self.mother=mother
        self.father=father
        self.foo=foo
        self.bar=bar


--------------------------------------------------
fview.py
--------------------------------------------------
from zope.app.form.browser import ObjectWidget
from zope.app.form.browser.editview import EditView
from zope.app.form import CustomWidgetFactory
from person import Person
from ifamily import IFamily

# here you define custom object widgets factories
# for father and mother
father_w = CustomWidgetFactory(ObjectWidget, Person)
mother_w = CustomWidgetFactory(ObjectWidget, Person)

class FamilyEditView(EditView):
    """View for editing a family"""

    __used_for__ = IFamily

    # since widget use the naming convention "fieldname" + "_widget"
    # you can define object widgets like this
    father_widget = father_w
    mother_widget = mother_w


--------------------------------------------------
configure.xml
--------------------------------------------------
<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    >
  <content class=".family.Family">
    <require
      permission="zope.View"
      interface=".ifamily.IFamily"
      />
    <require
      permission="zope.ManageContent"
      set_schema=".ifamily.IFamily"
      />
  </content>

  <content class=".person.Person">
    <!-- the right interface defining the VIEW attr and fields -->
    <require permission="zope.View"
        interface=".iperson.IPerson"
        />
    <!-- the right interface defining the EDIT attr and fields -->
    <require permission="zope.ManageContent"
        set_schema=".iperson.IPerson"
        />
  </content>

  <browser:editform
    schema=".ifamily.IFamily"
    class=".fview.FamilyEditView"
    label="Change Family Information"
    name="edit.html"
    menu="zmi_views" title="Edit"
    permission="zope.ManageContent"
    />

  <browser:addform
    schema=".ifamily.IFamily"
    class=".fview.FamilyEditView"
    label="Add family information"
    content_factory=".family.Family"
    name="AddFamily.html"
    permission="zope.ManageContent" 
    />

  <browser:addMenuItem
    class=".family.Family"
    title="Family"
    permission="zope.ManageContent"
    view="AddFamily.html"
    />
</configure>

-------------------------------------------------------
error when trying to make Family and Person persistent:
-------------------------------------------------------
Header
Exception traceback
Time
Mon Apr 25 03:36:28 2005
User
mngr, zope.manager, Manager,
Request URL
http://laptop:8080/bla/f/@@edit.html
Exception Type
UnpickleableError
Exception Value
Cannot pickle <type 'zope.security._proxy._Proxy'> objects
Traceback


Traceback (innermost last):

    * Module zope.publisher.publish, line 143, in publish
      publication.afterCall(request, object)
    * Module zope.app.publication.browser, line 70, in afterCall
      super(BrowserPublication, self).afterCall(request, ob)
    * Module zope.app.publication.zopepublication, line 161, in afterCall
      txn.commit()
    * Module transaction._transaction, line 327, in commit
      self._commitResources(subtransaction)
    * Module transaction._transaction, line 377, in _commitResources
      rm.commit(self)
    * Module ZODB.Connection, line 340, in commit
      self._store_objects(ObjectWriter(obj), transaction)
    * Module ZODB.Connection, line 362, in _store_objects
      p = writer.serialize(obj) # This calls __getstate__ of obj
    * Module ZODB.serialize, line 330, in serialize
      return self._dump(meta, obj.__getstate__())
    * Module ZODB.serialize, line 339, in _dump
      self._p.dump(state)

UnpickleableError: Cannot pickle <type 'zope.security._proxy._Proxy'> objects

Display traceback as text
REQUEST
CONNECTION_TYPE : keep-alive
CONTENT_TYPE : multipart/form-data; boundary=---------------------------1143408282188213258559412924
HTTP_REFERER : http://laptop:8080/bla/f/@@edit.html
field.bar : bar
SERVER_SOFTWARE : zope.server.http (HTTP)
SCRIPT_NAME :
CHANNEL_CREATION_TIME : 1114392974.74
REQUEST_METHOD : POST
HTTP_HOST : laptop:8080
PATH_INFO : /bla/f/@@edit.html
SERVER_PROTOCOL : HTTP/1.1
QUERY_STRING :
field.foo : foo ff
field.mother.name : my mum
CONTENT_LENGTH : 670
HTTP_ACCEPT_CHARSET : ISO-8859-1,utf-8;q=0.7,*;q=0.7
HTTP_USER_AGENT : Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.5) Gecko/20041129 Firefox/1.0 (Debian package 1.0-3.backports.org.1)
field.father.name : dad
SERVER_NAME : laptop
REMOTE_ADDR : 192.168.1.3
GATEWAY_INTERFACE : CGI/1.1
HTTP_ACCEPT_LANGUAGE : en-us,en;q=0.5
SERVER_PORT : 8080
HTTP_ACCEPT : text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
UPDATE_SUBMIT : Change
HTTP_ACCEPT_ENCODING : gzip,deflate
HTTP_KEEP_ALIVE : 300


More information about the Zope3-users mailing list