[Z3-sqlos] [Fwd: sqlos: add view for SQLOS objects]

Christian Lück christian.lueck at ruhr-uni-bochum.de
Mon Jan 9 21:26:01 CET 2006


-------- Original Message --------
Subject: sqlos: add view for SQLOS objects
Date: Sat, 07 Jan 2006 18:20:42 +0000
From: Christian Lück <christian.lueck at ruhr-uni-bochum.de>
To: z3base <z3 at codespeak.net>

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.

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.

- 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.

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


Kind regards,
Christian


PS 2006-01-09: Brian already posted an answer:
http://codespeak.net/pipermail/z3/2006-January/000043.html



More information about the z3-sqlos mailing list