[Zope3-Users] Oh no, doncha violate the o-v-p
Christian Lueck
christian.lueck at ruhr-uni-bochum.de
Thu Sep 29 12:11:51 EDT 2005
Hi,
I found a relatively easy way to write an addview for multiple objects.
As this violates the object view paradigm (o-v-p) I'd like to have your
expert critiques/comments: Are there any risks regarding the violation?
The task was to have one view V to create two objects A and B. A is a
container, B is contained in A. There must not be an empty A container,
one item at least.
I wrote a viewclass based on formlib, which makes it very easy to
generate fields from multiple schemas. (But this flexibility seems to be
intented for cases different from mine...)
The thing is to customize the createAndAdd method to call create- and
add-methods specified for both A and B (see sourcecode of
formlib.from.AddFormBase).
In my concrete case 'A' is 'Example' and 'B' is 'ExampleResourceSet'.
The major problem was the addExampleResourceSet method (see below last
method of code).
class ExampleAddView(form.AddForm):
<snip>
def createAndAdd(self, data):
obExample = self.createExample(data)
obExampleResourceSet = self.createExampleResourceSet(data)
notify(ObjectCreatedEvent(obExample))
notify(ObjectCreatedEvent(obExampleResourceSet))
instExample = self.addExample(obExample)
instExampleResourceSet =
self.addExampleResourceSet(obExampleResourceSet, instExample)
return instExample, instExampleResourceSet
def createExample(self, data):
"""Pass Example related form values to an Example factory."""
example_factory = zapi.getUtility(IFactory,
u"example.ExampleFactory_AddForm")
example = example_factory(
einheitsacht = self.session_data['einheitsacht'],
example_orig_lang = data['example_orig_lang'],
example_x_lang = [])
return example
def createExampleResourceSet(self, data):
example_resource_set_factory = zapi.getUtility(IFactory,
u"example.ExampleResourceSetFactory_AddForm")
example_resource_set = example_resource_set_factory(
resource = self.session_data['resource'],
example = data['example'],
quotation = data['quotation'],
page = data['page'])
return example_resource_set
_finished_add = False
_finished_addExample = False
_finished_addExampleResourceSet = False
_example_name = u"__stillunkown__"
def addExample(self, object):
ob = self.context.add(object)
self._finished_addExample = True
if self._finished_addExample and
self._finished_addExampleResourceSet:
self._finished_add = True
return ob
def addExampleResourceSet(self, content, container):
"""PROBLEM: no IAdding regarding container.
So code this following the lines of the IAdding implementation
in zope.app.container.browser.adding.Adding ."""
name = None
# check precondition
checkObject(container, name, content)
if self._finished_addExample:
# choose a name
if IContainerNamesContainer.providedBy(container):
name = INameChooser(container).chooseName('', content)
else:
"""Exception since we don't want to choose a name by
hand."""
err = "container %s does not implement
IContainerNamesContainer" % container
raise Exception_ExampleAddView, err
# Create the object.
container[name] = content
# set status tings
self._finished_addExampleResourceSet = True
self._finished_add = True
return container[name]
else:
err = "Unable to create ExampleResourceSet _before_ Example"
raise Exception_ExampleAddView, err
<snip>
Note: Both content classes implement IContainerNamesContainer.
In the addExample method the codeline
ob = self.context.add(object)
calls the add method defined by IAdding (or rather its implementation,
the magic /+/ ;). But since there is no IAdding context regarding the
new created Example object we have to 'hardcode' the add method for the
ExampleResourceSet object. I did that following and adapting the lines
of the IAdding implementation of zope.app.container.browser.adding.Adding.
Best regards,
Christian
PS. If you wonder about the class name 'Example' -- the application is
supposed to be a database to collect examples and metaphors (rhetorical
figures) and will be part of a project located at the department for
german language and literature at the Ruhr-University Bochum, germany.
More information about the Zope3-users
mailing list