[Zope3-Users] Cache values must be persistent objects. -
ZODB3-3.9.0_dev_r77011-py2.4-linux-i686.egg
Andreas Reuleaux
reuleaux at web.de
Thu Aug 9 22:31:38 EDT 2007
The example below (contacts) works fine for me with a recent svn
checkout of the 3.4 branch, i e
svn co svn://svn.zope.org/repos/main/Zope3/branches/3.4 z3
but I get errors with a recent eggs installation via zc.buildout
(when trying to edit and save a contact, see below)
...
File "/home/reuleaux/z3eggs/tmp17mUe4/ZODB3-3.9.0_dev_r77011-py2.4-linux-i686.egg/ZODB/Connection.py", line 58
3, in _commit
File "/home/reuleaux/z3eggs/tmp17mUe4/ZODB3-3.9.0_dev_r77011-py2.4-linux-i686.egg/ZODB/Connection.py", line 63
5, in _store_objects
TypeError: Cache values must be persistent objects.
It seems other people where having similar troubles, see e. g.
http://www.nabble.com/Problems-with-ZODB3-3.9.0_dev_r77011-t4109664.html
however it is not obvious to me how to exactly apply the solutions proposed
there to my code - there is no external file (like an image) involved in
my code.
The example is not to long, however it is not trivial:
uses formlib, an object in its schema,
object widgets, object widget dispatcher etc.
- I have therefore included the complete example. -
for convenience: I have also put it online (my old university account)
$ wget -nd http://user.cs.tu-berlin.de/~reuleaux/contacts.tgz
$ tar xvpzf contacts.tgz
$ cd contacts
edit buildout.cfg as you see fit, you might for example change
the eggs-directory
maybe adjust the mngr user/passwd in src/contacts/app.zcml
$ python bootstrap
$ ./bin/buildout
$ ./bin/instance start
usage / steps to reproduce:
go to http://localhost:8080
log in as mngr and add some contacts - that works fine
now edit such a contact (say I have given it a name rx)
http://localhost:8080/rx/edit
and try to save it: boom!
I am aware that object widgets are kind of superseeded with
the advent of z3c.form - and I really want to go in that direction
but for the time being my programming would be much more relaxed
if I got this example working,
I could really need a helping hand here, thanks.
-Andreas
--------------------
interfaces.py
--------------------
from zope.interface import Interface
from zope.schema import TextLine, Object
class IAddr(Interface):
"""an address.
"""
street = TextLine(
title=u"street",
description=u"the street",
required=False,
missing_value=u''
)
city = TextLine(
title=u"city",
description=u"the city",
required=False,
missing_value=u''
)
zipcode = TextLine(
title=u"zip",
description=u"the zip code",
required=False,
missing_value=u''
)
class IContact(Interface):
"""a contact
"""
name = TextLine(
title=u"name",
description=u"the name",
required=False,
missing_value=u''
)
firstname = TextLine(
title=u"firstname",
description=u"the firstname",
required=False,
missing_value=u''
)
addr=Object(
title=u'address',
description=u'the address',
required = False,
schema=IAddr)
--------------------
addr.py
--------------------
from zope.interface import implements
from interfaces import IAddr
from zope.schema.fieldproperty import FieldProperty
from persistent import Persistent
class Addr(Persistent):
"""Eine Addr."""
implements(IAddr)
street = FieldProperty(IAddr['street'])
city = FieldProperty(IAddr['city'])
zipcode = FieldProperty(IAddr['zipcode'])
def __init__(self,
street=u'',
city=u'',
zipcode=u'',
titel=u'',
geb=u'',
fkt=u''):
self.street=street
self.city=city
self.zipcode=zipcode
--------------------
contact.py
--------------------
from zope.interface import implements
from interfaces import IContact
from zope.schema.fieldproperty import FieldProperty
from persistent import Persistent
from zope.security.proxy import removeSecurityProxy
# from zope.app.container.contained import Contained
# class Contact(Contained, Persistent):
class Contact(Persistent):
"""a contact."""
implements(IContact)
__name__ = __parent__ = None
name = FieldProperty(IContact['name'])
firstname=FieldProperty(IContact['firstname'])
addr = FieldProperty(IContact['addr'])
def __init__(self,
name=u'',
firstname=u'',
addr=None,
):
self.name=name
self.firstname=firstname
self.addr=addr
# def __getstate__(self):
# s=Persistent.__getstate__(self)
# s['addr']=removeSecurityProxy(self.addr)
# return s
--------------------
views.py
--------------------
from zope.formlib import form, namedtemplate
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from interfaces import IContact
from contact import Contact
# wohl nicht mehr noetig
# cform = namedtemplate.NamedTemplateImplementation(
# ViewPageTemplateFile('contactform.pt'))
class ContactAddForm(form.AddForm):
form_fields = form.Fields(IContact)
# template = namedtemplate.NamedTemplate('cf')
def create(self, data):
c=Contact()
for k in data.keys():
setattr(c, k, data[k])
return c
# import logging
class ContactEditForm(form.EditForm):
form_fields = form.Fields(IContact)
# def handle_edit_action(self, action, data):
#logging.log(self)
# super(ContactEditForm, self).handle_edit_action.success(data)
--------------------
widgets.py
--------------------
from zope.app.form.browser import ObjectWidget
from contacts.addr import Addr
def AddrWidget(context, obj, request):
w=ObjectWidget(context, request, Addr)
sty={'street': 'width: 105px;',
}
for k in sty.keys():
sw=w.getSubWidget(k)
sw.style=sty[k]
sw.cssClass='in'
return w
--------------------
objectwidgetdispatcher.py
--------------------
# -===objectwidgetdispatcher.py===-
from zope.app import zapi
from zope.interface import implements
from zope.app.form.interfaces import IInputWidget
def ObjectInputWidget(context, request):
"""Dispatch widget for Object schema field to a widget that is
registered for (IObject, schema, IBrowserRequest) where schema
is the schema of the object."""
class Obj(object):
implements(context.schema)
widget=zapi.getMultiAdapter((context, Obj(), request), IInputWidget)
return widget
--------------------
configure.zcml
--------------------
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
>
<class class=".addr.Addr">
<require
permission="zope.View"
interface=".interfaces.IAddr"
/>
<require
permission="zope.ManageContent"
set_schema=".interfaces.IAddr"
/>
</class>
<class class=".contact.Contact">
<factory
id="contact.Contact"
title="Create a new contact entry"
description="This factory instantiates new contacts"
/>
<require
permission="zope.View"
interface=".interfaces.IContact"
/>
<require
permission="zope.ManageContent"
set_schema=".interfaces.IContact"
/>
</class>
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.schema.interfaces.IObject"
provides="zope.app.form.interfaces.IInputWidget"
factory=".objectwidgetdispatcher.ObjectInputWidget"
permission="zope.Public"
/>
<view
type="zope.publisher.interfaces.browser.IBrowserRequest"
for="zope.schema.interfaces.IObject .interfaces.IAddr"
provides="zope.app.form.interfaces.IInputWidget"
factory=".widgets.AddrWidget"
permission="zope.Public"
/>
<!-- adapter factory=".views.cform"
for=".views.ContactAddForm"
name="cf"
/ -->
<browser:addform
schema=".interfaces.IContact"
class=".views.ContactAddForm"
label="Add a Contact"
name="add"
permission="zope.ManageContent"
/>
<browser:addMenuItem
title="Contact"
class=".contact.Contact"
permission="zope.ManageContent"
view="add"
/>
<browser:page
for=".interfaces.IContact"
class=".views.ContactEditForm"
name="edit"
permission="zope.ManageContent"
menu="zmi_views"
title="Edit"
/>
</configure>
More information about the Zope3-users
mailing list