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
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
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
--
http://namespaces.zope.org/zope";
xmlns:browser="http://namespaces.zope.org/browser";
>
---
error when trying