[Checkins] SVN: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/ Added the fourth demo. This one demonstrates the combination of the Dublin Core adapter with a nested container object.

Michael Bernstein webmaven at cox.net
Tue Jan 16 22:59:10 EST 2007


Log message for revision 72061:
  Added the fourth demo. This one demonstrates the combination of the Dublin Core adapter with a nested container object.
  

Changed:
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/__init__.py
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/__init__.py
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/configure.zcml
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/fragment_view.pt
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/message.py
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/view.pt
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/configure.zcml
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/container.py
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/interfaces.py
  A   z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/message.py

-=-
Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/__init__.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/__init__.py	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/__init__.py	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1 @@
+# Make this a package

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/__init__.py
===================================================================

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/configure.zcml
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/configure.zcml	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/configure.zcml	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,94 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:browser="http://namespaces.zope.org/browser"
+  >
+
+<!-- Message Container -->
+
+  <browser:addMenuItem
+    title="Message Container 4"
+    class="z3c.zalchemy.demo.demo_4.container.MessageContainer4"
+    permission="zope.ManageContent"
+    />
+
+  <browser:containerViews
+    for="z3c.zalchemy.demo.demo_4.interfaces.IMessageContainer4"
+    contents="zope.ManageContent"
+    index="zope.View"
+    add="zope.ManageContent"
+    />
+
+<!-- Message -->
+
+  <browser:addMenuItem
+      title="Hello World Message"
+      factory="z3c.zalchemy.demo.demo_4.message.HelloWorldMessage4"
+      view="z3c.zalchemy.demo.demo_4.message.HelloWorldMessage4"
+      permission="zope.ManageContent"
+      />
+
+  <browser:containerViews
+    for="z3c.zalchemy.demo.demo_4.interfaces.IHelloWorldMessage4"
+    contents="zope.ManageContent"
+    index="zope.View"
+    add="zope.ManageContent"
+    />
+
+  <browser:page
+      for="z3c.zalchemy.demo.demo_4.interfaces.IHelloWorldMessage4"
+      name="view.html"
+      template="view.pt"
+      permission="zope.View"
+      menu="zmi_views" title="View"
+      />
+
+  <browser:page
+      for="zope.app.container.interfaces.IAdding"
+      name="z3c.zalchemy.demo.demo_4.message.HelloWorldMessage4"
+      class=".message.AddHelloWorldMessage"
+      permission="zope.ManageContent" 
+      />
+
+  <browser:page
+    for="z3c.zalchemy.demo.demo_4.interfaces.IHelloWorldMessage4"
+    name="edit.html"
+    class=".message.EditHelloWorldMessage"
+    permission="zope.ManageContent"
+    menu="zmi_views" title="Edit"
+    />
+
+
+<!-- Message Fragment -->
+
+  <browser:addMenuItem
+      title="Hello World Message Fragment"
+      factory="z3c.zalchemy.demo.demo_4.message.HelloWorldFragment"
+      view="z3c.zalchemy.demo.demo_4.message.HelloWorldFragment"
+      permission="zope.ManageContent"
+      />
+
+  <browser:page
+      for="z3c.zalchemy.demo.demo_4.interfaces.IHelloWorldFragment"
+      name="index.html"
+      template="fragment_view.pt"
+      permission="zope.View"
+      menu="zmi_views" title="View"
+      />
+
+  <browser:page
+      for="zope.app.container.interfaces.IAdding"
+      name="z3c.zalchemy.demo.demo_4.message.HelloWorldFragment"
+      class=".message.AddHelloWorldFragment"
+      permission="zope.ManageContent" 
+      />
+
+  <browser:page
+    for="z3c.zalchemy.demo.demo_4.interfaces.IHelloWorldFragment"
+    name="edit.html"
+    class=".message.EditHelloWorldFragment"
+    permission="zope.ManageContent"
+    menu="zmi_views" title="Edit"
+    />
+
+
+</configure>

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/fragment_view.pt
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/fragment_view.pt	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/fragment_view.pt	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,10 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+  <h1>This fragment is a <span tal:replace="context/what">What</span>.</h1>
+</div>
+</body>
+</html>

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/message.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/message.py	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/message.py	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,48 @@
+import zope.traversing.browser
+from zope.app.pagetemplate import ViewPageTemplateFile
+from zope.formlib.namedtemplate import NamedTemplateImplementation
+from zope.formlib import form
+from z3c.zalchemy.demo.demo_4.interfaces import IHelloWorldMessage4, IHelloWorldFragment
+from z3c.zalchemy.demo.demo_4.message import HelloWorldMessage4, HelloWorldFragment
+from zope.dublincore.interfaces import IZopeDublinCore
+
+class AddHelloWorldMessage(form.AddForm):
+
+    form_fields = form.FormFields(IZopeDublinCore).select('title', 'description')+form.FormFields(IHelloWorldMessage4).omit('__parent__','className')
+
+    def create(self, data):
+        return HelloWorldMessage4(**data)
+
+class EditHelloWorldMessage(form.EditForm):
+
+    form_fields = form.FormFields(IZopeDublinCore).select('title', 'description')+form.FormFields(IHelloWorldMessage4).omit('__parent__','className')
+
+    actions = form.EditForm.actions.copy()
+
+    @form.action(_("Apply and View"))
+    def handle_edit_view_action(self, action, data):
+        self.actions['form.actions.apply'].success(data)
+        url = zope.traversing.browser.absoluteURL(self.context, self.request)
+        self.request.response.redirect(url)
+
+class AddHelloWorldFragment(form.AddForm):
+
+    form_fields = form.FormFields(IHelloWorldFragment).omit('__parent__')
+
+    def create(self, data):
+        return HelloWorldFragment(**data)
+
+class EditHelloWorldFragment(form.EditForm):
+
+    form_fields = form.FormFields(IHelloWorldFragment).omit('__parent__')
+
+    actions = form.EditForm.actions.copy()
+
+    @form.action(_("Apply and View"))
+    def handle_edit_view_action(self, action, data):
+        self.actions['form.actions.apply'].success(data)
+        url = zope.traversing.browser.absoluteURL(self.context, self.request)
+        self.request.response.redirect(url)
+
+view_template = NamedTemplateImplementation(
+    ViewPageTemplateFile('view.pt'))

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/view.pt
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/view.pt	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/browser/view.pt	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,14 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+  <h1 tal:content="context/zope:title">Title</h1>
+  <p tal:content="context/zope:description">The description</p>
+  <h2>Hello <span tal:replace="context/who">Who</span>!</h2>
+  <p tal:content="context/fragments">fragment</p>
+</div>
+</body>
+</html>

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/configure.zcml
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/configure.zcml	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/configure.zcml	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,122 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:alchemy="http://namespaces.zalchemy.org/alchemy">
+
+  <!-- ZAlchemy Setup -->
+
+  <alchemy:engine
+      name="DemoEngine-4"
+      url="sqlite:///zalchemy.message_4.db"
+      />
+      
+  <alchemy:connectTable
+      table="message"
+      engine="DemoEngine-4"
+      />
+  <alchemy:connectTable
+      table="dublin_core"
+      engine="DemoEngine-4"
+      />
+  <alchemy:connectTable
+      table="fragment"
+      engine="DemoEngine-4"
+      />
+      
+  <alchemy:connectClass
+      class=".message.RelationalDC"
+      engine="DemoEngine-4"
+      />
+  <alchemy:connectClass
+      class=".message.HelloWorldMessage4"
+      engine="DemoEngine-4"
+      />
+  <alchemy:connectClass
+      class=".message.HelloWorldFragment"
+      engine="DemoEngine-4"
+      />
+      
+  <!-- Message Container Configuration -->
+
+  <class class=".container.MessageContainer4">
+
+    <factory
+        id="z3c.zalchemy.demo.demo_4.container.MessageContainer4"
+        title="Message Container 3"
+        description="A container for Hello World Message instances" />
+
+    <require
+        permission="zope.View"
+        interface="zope.app.container.interfaces.IReadContainer"
+        />
+
+    <require
+        permission="zope.ManageContent"
+        interface="zope.app.container.interfaces.IWriteContainer"
+        />
+
+  </class>
+
+
+  <!-- Message Configuration -->
+
+  <class class=".message.HelloWorldMessage4">
+    <require
+      permission="zope.View"
+      interface=".interfaces.IHelloWorldMessage4"
+      />
+
+    <require
+        permission="zope.ManageContent"
+        set_schema=".interfaces.IHelloWorldMessage4"
+        />
+
+  </class>
+
+  <utility
+    component=".message.messageFactory"
+    name="z3c.zalchemy.demo.demo_4.message.HelloWorldMessage4"
+    />
+
+
+  <!-- Message Fragment Configuration -->
+
+  <class class=".message.HelloWorldFragment">
+    <require
+      permission="zope.View"
+      interface=".interfaces.IHelloWorldFragment"
+      />
+
+    <require
+        permission="zope.ManageContent"
+        set_schema=".interfaces.IHelloWorldFragment"
+        />
+
+  </class>
+
+  <utility
+    component=".message.fragmentFactory"
+    name="z3c.zalchemy.demo.demo_4.message.HelloWorldFragment"
+    />
+
+
+  <!-- Dublin Core Adapter Configuration -->
+  
+    <adapter 
+      factory=".message.RelationalDCAdapter"
+      permission="zope.View" />
+
+  <class class=".message.RelationalDC">
+    <require
+      permission="zope.View"
+      interface="zope.dublincore.interfaces.IZopeDublinCore"
+      />
+
+    <require
+        permission="zope.ManageContent"
+        set_schema="zope.dublincore.interfaces.IZopeDublinCore"
+        />
+  </class>
+
+  <include package=".browser" />
+
+</configure>

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/container.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/container.py	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/container.py	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,87 @@
+from zope.app.container.contained import Contained
+from persistent import Persistent
+from zope.interface import implements
+
+import z3c.zalchemy
+from z3c.zalchemy.container import contained
+
+from interfaces import IMessageContainer4
+from message import HelloWorldMessage4
+
+
+    
+class MessageContainer4(Persistent, Contained):
+    implements(IMessageContainer4)
+
+    def keys(self):
+        for name, obj in self.items():
+            yield name
+
+    def values(self):
+        for name, obj in self.items():
+            yield obj
+
+    def __iter__(self):
+        return iter(self.keys())
+
+    def items(self):
+        session = z3c.zalchemy.getSession()
+        query = session.query(HelloWorldMessage4)
+        for obj in query.select():
+            name = self._toStringIdentifier(obj)
+            yield (name, contained(obj, self, name) )
+
+    def __getitem__(self, name):
+        if not isinstance(name, basestring):
+            raise KeyError, "%s is not a string" % name
+        obj = self._fromStringIdentifier(name)
+        if obj is None:
+            raise KeyError(name)
+        return contained(obj, self, name)
+
+    def get(self, name, default=None):
+        try:
+            return self[name]
+        except KeyError:
+            return default
+    
+    def __contains__(self, name):
+        return self.get(name) is not None
+
+    def __len__(self):
+        try:
+            session = z3c.zalchemy.getSession()
+            query = session.query(HelloWorldMessage4)
+            return query.count()
+        except sqlalchemy.exceptions.SQLError:
+            # we don't want an exception in case of database problems
+            return 0
+
+    def __delitem__(self, name):
+        obj = self[name]
+        #TODO: better delete objects using a delete adapter
+        #      for dependency handling.
+        session = z3c.zalchemy.getSession()
+        session.delete(obj)
+
+    def __setitem__(self, name, item):
+        session = z3c.zalchemy.getSession()
+        session.save(item)
+        session.flush()
+
+    def _toStringIdentifier(self, obj):
+        session = z3c.zalchemy.getSession()
+        mapper = session.mapper(HelloWorldMessage4)
+        instance_key = mapper.instance_key(obj)
+        ident = '-'.join(map(str, instance_key[1]))
+        return 'HelloWorldMessage4-'+ident
+
+    def _fromStringIdentifier(self, name):
+        prefix = 'HelloWorldMessage4' + '-'
+        if not name.startswith(prefix):
+            return None
+
+        ident = name[len(prefix):]
+        session = z3c.zalchemy.getSession()
+        return session.query(HelloWorldMessage4).get(ident)
+

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/interfaces.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/interfaces.py	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/interfaces.py	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,34 @@
+import zope.schema
+from z3c.zalchemy.interfaces import ISQLAlchemyObjectContained, ISQLAlchemyContainer
+from zope.app.container.constraints import contains, containers
+from zope.interface import Interface, Attribute
+
+class IHelloWorldFragment(ISQLAlchemyObjectContained):
+    """Information about a hello world message"""
+    
+    message_id = Attribute("The ID of the parent message")
+
+    what = zope.schema.TextLine(
+        title=u'What',
+        description=u'Type of message',
+        required=True)
+        
+        
+class IHelloWorldMessage4(ISQLAlchemyContainer,ISQLAlchemyObjectContained):
+    """Information about a hello world message"""
+
+    id = Attribute("The ID of the Message")
+    
+    fragments = Attribute("The contained Message fragments")
+    
+    who = zope.schema.TextLine(
+        title=u'Who',
+        description=u'Name of the person getting the message',
+        required=True)
+    contains(IHelloWorldFragment)
+
+
+class IMessageContainer4(ISQLAlchemyContainer):
+    """A container for hello world message mbjects"""
+    contains(IHelloWorldMessage4)
+    

Added: z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/message.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/message.py	2007-01-17 02:54:47 UTC (rev 72060)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/demo/demo_4/message.py	2007-01-17 03:59:09 UTC (rev 72061)
@@ -0,0 +1,229 @@
+from datetime import datetime
+
+import sqlalchemy
+
+import z3c.zalchemy
+from z3c.zalchemy.container import SQLAlchemyNameChooser, contained
+
+from zope.app.container.contained import Contained
+from zope.interface import implements
+from zope.component import adapts
+from zope.schema.fieldproperty import FieldProperty
+from zope.component.factory import Factory
+from zope.dublincore.interfaces import IZopeDublinCore
+
+from interfaces import IHelloWorldMessage4, IHelloWorldFragment
+
+
+RelationalDCTable = sqlalchemy.Table(
+        'dublin_core',
+        z3c.zalchemy.metadata,
+        sqlalchemy.Column('id', sqlalchemy.Integer,
+                           sqlalchemy.Sequence('metadata_seq'),
+                           primary_key = True),
+        sqlalchemy.Column('title', sqlalchemy.Unicode),
+        sqlalchemy.Column('description', sqlalchemy.Unicode),
+        sqlalchemy.Column('created', sqlalchemy.DateTime),
+        sqlalchemy.Column('modified', sqlalchemy.DateTime)
+        )
+        
+z3c.zalchemy.createTable('dublin_core', 'DemoEngine-4')
+
+
+HelloWorldMessageTable4 = sqlalchemy.Table(
+        'message',
+        z3c.zalchemy.metadata,
+        sqlalchemy.Column('id', sqlalchemy.Integer,
+                           sqlalchemy.ForeignKey(RelationalDCTable.c.id),
+                           primary_key = True,
+                           autoincrement = False),
+        sqlalchemy.Column('who', sqlalchemy.Unicode),
+        )
+
+z3c.zalchemy.createTable('message', 'DemoEngine-4')
+
+
+HelloWorldFragmentTable = sqlalchemy.Table(
+        'fragment',
+        z3c.zalchemy.metadata,
+        sqlalchemy.Column('id', sqlalchemy.Integer,
+                           primary_key = True),
+        sqlalchemy.Column('message_id', sqlalchemy.Integer,
+                          sqlalchemy.ForeignKey(HelloWorldMessageTable4.c.id)),
+        sqlalchemy.Column('what', sqlalchemy.Unicode),
+        )
+
+z3c.zalchemy.createTable('fragment', 'DemoEngine-4')
+
+
+class RelationalDC(object):
+    
+    creators = FieldProperty(IZopeDublinCore['creators'])
+    title = FieldProperty(IZopeDublinCore['title'])
+    description = FieldProperty(IZopeDublinCore['description'])
+    created = FieldProperty(IZopeDublinCore['created'])
+    modified = FieldProperty(IZopeDublinCore['modified'])
+    
+    
+    def __init__(self, title=None, description=None, created=None,
+                 modified=None):
+        self.title = title
+        self.description = description
+        if created is None:
+            self.created = datetime.now()
+        else:
+            self.created = created
+        if modified is None:
+            self.modified = datetime.now()
+        else:
+            self.modified = modified
+
+            
+relationalmapper = sqlalchemy.mapper(RelationalDC, RelationalDCTable)
+
+class RelationalDCAdapter(object):
+    adapts(IHelloWorldMessage4)
+    implements(IZopeDublinCore)
+    
+    def __init__(self, context):
+        self.context = context
+        self.__parent__ = context
+        session = z3c.zalchemy.getSession()
+        query =  session.query(RelationalDC).select_by(id=context.id)
+        self.result = None
+        try:
+            self.result = query[0]
+        except IndexError:
+            pass
+        
+    def getCreators(self):
+        return ()
+    
+    def setCreators(self, creators):
+        pass
+        
+    creators = property(getCreators, setCreators, doc="RelationalDC creators")
+        
+    def getTitle(self):
+        return self.result.title
+    
+    def setTitle(self, title):
+        self.result.title = title
+        
+    title = property(getTitle, setTitle, doc="RelationalDC title")
+            
+    def getDescription(self):
+        return self.result.description
+    
+    def setDescription(self, description):
+        self.result.description = description
+        
+    description = property(getDescription, setDescription,
+                           doc="RelationalDC description")
+                           
+
+
+class HelloWorldFragment(Contained):
+    implements(IHelloWorldFragment)                           
+
+    what = FieldProperty(IHelloWorldFragment['what'])
+
+    def __init__(self, what):
+        self.what = what
+
+fragmentmapper = sqlalchemy.mapper(HelloWorldFragment, HelloWorldFragmentTable)
+
+
+class HelloWorldMessage4(Contained):
+    implements(IHelloWorldMessage4)
+
+    who = FieldProperty(IHelloWorldMessage4['who'])
+
+    def __init__(self, title, description, who):
+        self.rdc = RelationalDC(title, description)
+        self.who = who
+
+
+    def keys(self):
+        for name, obj in self.items():
+            yield name
+
+    def values(self):
+        for name, obj in self.items():
+            yield obj
+
+    def __iter__(self):
+        return iter(self.keys())
+
+    def items(self):
+        for obj in self.fragments:
+            name = self._toStringIdentifier(obj)
+            yield (name, contained(obj, self, name) )
+
+    def __getitem__(self, name):
+        if not isinstance(name, basestring):
+            raise KeyError, "%s is not a string" % name
+        obj = self._fromStringIdentifier(name)
+        if obj is None:
+            raise KeyError(name)
+        return contained(obj, self, name)
+
+    def get(self, name, default=None):
+        try:
+            return self[name]
+        except KeyError:
+            return default
+    
+    def __contains__(self, name):
+        return self.get(name) is not None
+
+    def __len__(self):
+        return len(self.fragments)
+        
+    def __delitem__(self, name):
+        obj = self[name]
+        #TODO: better delete objects using a delete adapter
+        #      for dependency handling.
+        session = z3c.zalchemy.getSession()
+        session.delete(obj)
+
+    def __setitem__(self, name, item):
+        session = z3c.zalchemy.getSession()
+        self.fragments.append(item)
+        session.flush()
+
+    def _toStringIdentifier(self, obj):
+        session = z3c.zalchemy.getSession()
+        mapper = session.mapper(HelloWorldFragment)
+        instance_key = mapper.instance_key(obj)
+        ident = '-'.join(map(str, instance_key[1]))
+        return 'HelloWorldFragment-'+ident
+
+    def _fromStringIdentifier(self, name):
+        prefix = 'HelloWorldFragment' + '-'
+        if not name.startswith(prefix):
+            return None
+
+        ident = name[len(prefix):]
+        session = z3c.zalchemy.getSession()
+        return session.query(HelloWorldFragment).get_by(id=ident)
+
+
+messagemapper = sqlalchemy.mapper(HelloWorldMessage4, HelloWorldMessageTable4)
+messagemapper.add_property('rdc', sqlalchemy.relation(RelationalDC,
+                                                      cascade="delete"))
+messagemapper.add_property('fragments',
+                           sqlalchemy.relation(HelloWorldFragment,
+                                               cascade="delete"))
+
+messageFactory=Factory(
+    HelloWorldMessage4,
+    title=u"Create a new message",
+    description=u"This factory instantiates new messages"
+    )
+    
+fragmentFactory=Factory(
+    HelloWorldFragment,
+    title=u"Create a new message fragment",
+    description=u"This factory instantiates new message fragments"
+    )



More information about the Checkins mailing list