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>
_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to