[z3] sqlos: add view for SQLOS objects

Brian Sutherland jinty at web.de
Mon Jan 9 02:45:36 CET 2006


On Sat, Jan 07, 2006 at 06:20:42PM +0000, Christian Lück wrote:
> Hi!
> 
> I yust found out how to implement add views for a SQLOS-inheriting
> content component. Since it might be interisting for others I post it
> here. If this should be old hat to you, sorry.
> 
> The key to get an IAdding view for SQLOS objects running is that you
> have to leave the z3 standard two step add process. To put it short: You
> have to rewrite (leave away) the add() method for the add view
> (inherited from zope.app.form.browser.AddView or
> zope.formlib.form.AddFormBase).
> 
> More detailed:
> 
> The standard z3 prozess to add an object to a container is two steps:
> 1) Creation of the object by calling a factory.
> 2) Adding this object instance to a container.
> This is normally handled by a method of the add view called
> createAndAdd(). createAndAdd() again calls create() for step 1 and then
> add() for step 2.
> 
> Lets have a look at zope.formlib.form.AddFormBase :
> 
> class AddFormBase(FormBase):
> 
>     ### snip ###
> 
>     def createAndAdd(self, data):
>         ob = self.create(data)
>         zope.event.notify(
>             zope.app.event.objectevent.ObjectCreatedEvent(ob))
>         return self.add(ob)
> 
>     def create(self, data):
>         raise NotImplementedError(
>             "concrete classes must implement create() or createAndAdd()")
> 
>     _finished_add = False
> 
>     def add(self, object):
>         ob = self.context.add(object) # *<--- THE PROBLEM*
>         self._finished_add = True
>         return ob
> 
>     ### snip ###
> 
> Creating an SQLOS object differs from this standard inasmuch step 2 is
> not only not recommended (a) but even causes errors (b).
> 
> a) not recommended: As a consequence of the current sqlos implementation
>  all instances of a content component class inheriting from SQLOS go
> into the same rdb table. => Each container for this content component
> shows all the instances of this component. Imagine two containers with
> preconditions set for the same content component, each one will show a
> set union as its items. - That's why SQLOS objects are not really
> locateable.
> Corollar: Instantiating an content object, which inherits from SQLOS,
> lets this instance show up in each SQLObjectContainer with matching
> preconditions.

Yes, though it is possible to simulate this if every container has a
unique_id which is stored on the content object itself. There is an
"Isolated" container implementation in the source which does this.

There is no corresponding SQLOS implementation as the obvious
implementation is a multiple join and inheritance of 2 SQLObject
related classes was too risky.

> b) You simply can't add an SQLOS object to somewhere.
> someSQLObjectContainer['some_name'] = someSQLOSInstance causes diverse
> errors due to the logic of the current implementation. It would cost a
> >50 words analysis, so I leave it at the moment.
> 
> This in mind a possible implementation based on formlib would be:
> (my example is a Book(SQLOS) object)
> 
> class BookFormlibAddView(form.AddForm):
> 
>     form_fields = form.Fields(IBook)
> 
>     def create(self, data):
>         """Call a factory to instantiate an object."""
>         factory = zapi.getUtility(IFactory,
> u"quotationtool.BookWithInitialValues")
>         obj = factory(
>             lang = data['lang'],
>             is_original = data['is_original'],
>             abbrev_orig_title = data['abbrev_orig_title'],
>             ### snip ###
>             series = data['series'])
>         return obj
> 
>     def add(self, object):
>         #ob = self.context.add(object) # in sqlos we don't add an object
> to a container, so we don't need this
>         self._finished_add = True
>         #return ob
>         return object
> 
> *Note that this makes use of a factory* -- which is an other major
> problem that one faces with the current sqlos. Please refer to my other
> posting on it:
> http://www.mail-archive.com/zope3-users@zope.org/msg01423.html
> 
> Registration:
> 
>   <page
>       for="zope.app.container.interfaces.IAdding"
>       class=".book.BookFormlibAddView"
>       name="AddBookFL.html"
>       permission="quotationtool.AddResource"
>       />
> 
> This way one gets things working.
> 
> 
> Proposal / Desiderata:
> 
> - sqlos.container.SQLObjectContainer should be reimplemented to get
> standard add views ( = views for zope.app.container.interfaces.IAdding )
> going. Idea (but not more): Reimplement the methods of
> SQLContainerObjects which are called by the magic '+' ( = an
> implementation of IAdding), which is called by the standard z3 add()
> methods in zope.app.form.browser.add.AddView or
> zope.formlib.form.AddFormBase.

There is a testbrowser functional test in ftests/adding.txt which
actually tests the IAdding for a sampleperson. With the standard
browser:addform directive. A first step might be to extend that test so
that it fails.

> - still before, sqlos.container.SQLObjectContainer should be recoded to
> get it working with many factories registrated for a contained SQLOS
> content component. See my other posting for this problem.

My comments are there.

> - really locatable SQLOS objects would be nice, but I know this would be
> hard work...

I would love to have a look at any patches that make sqlos containers
work more like standard Zope 3 containers!

-- 
Brian Sutherland

Metropolis - "it's the first movie with a robot. And she's a woman.
              And she's EVIL!!"


More information about the z3 mailing list