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