[Zope3-dev] EditView bug?

Dominik Huber dominik.huber@perse.ch
Fri, 11 Jul 2003 09:40:29 +0200


stephan, thanks for the answer. i try to explain my assessemt...

target:
- one edit handler for data stored in the conent-object itself and
  in it attributesadapter
- using schema and the editview.py machinery

solution:
- define a overall schema derived from a content schema and
  a specific annotation schema
- define a adapter implementing the overall schema
- use the editview.py machinery for the overall adapter instead of the
content object

On Thursday 10 July, 2003 8:17 PM, Stephan Richter wrote:
>Right, people reported this before. The problem was somehow solved in some
way
>in the NewsSite product. You might want to look at it.

i already looked at three examples to figure out alternatives...

examples:
- newssite:
  it uses an own editform.pt
  to intransparent for my manner of understanding

- dublincore exp. metadataedit.py (MetaDataEdit):
  it uses an own dedicated update mechanism

- zwiki exp. wikipage: it's that what i'm looking for, but...
  the wikipage implements all the editable attributes itself and that's the
only
  reason why it works properly without any observable side effects

>But then, maybe your proposal is accepted. :-) I don't want to make the
call,
>since it might have greater implications or requirements.

questions:
why the edit-widgets get twice setuped?
- first setup during initialisation
- second setup during the update()-method call
(cmp. listing 1, EditView.__init__() and EditView.update())

why the editwidgets get setuped in two different ways?
- once with the content-paramater set to self.adapted
- and once without content-parameter what is
  equivalent to content = view.context (cmp. listing 2, _setUpWidgets())

possible changes:
- status quo: no changes
- remove the second edit-widget-setup-call in the update-method
- change second edit-widget-setup-call in the update-method:
  add parameter content: content=self.adapted

discussion of the possible changes:
- status quo:
  - side effects
  - the editview-machinery doesn't display all it potentialities
  i think this is no real option
- remove call:
  + get ride of the side effect
  + code optimisation
  i think it would be the best, but...
  - it might have greater implications or requirements.
- change call:
  + get ride of the side effect
  best price, low uncertainties, but still...
  - it might have implications or requirements.

regards, dominik

code listings:

listing 1:
zope/app/browser/form/editview.py

class EditView(BrowserView):
    ...

    def __init__(self, context, request):
        super(EditView, self).__init__(context, request)
        self._setUpWidgets() # XXX First setup

    def _setUpWidgets(self):
        adapted = getAdapter(self.context, self.schema)
        if adapted is not self.context:
            adapted = ContextWrapper(adapted, self.context,
name='(adapted)')
        self.adapted = adapted
        setUpEditWidgets(self, self.schema, names=self.fieldNames,
                         content=self.adapted)
        # XXX First setup: with content=self.adapted

    def apply_update(self, data):

        content = self.adapted  # here we get our correct content
(->adapter)

        errors = []
        unchanged = True

        for name in data:
            field = self.schema[name]
            try:
                newvalue = data[name]

                change = True

                change = field.query(content, self) != newvalue

                if change:
                    field.set(content, data[name])
                    unchanged = False

            except ValidationError, v:
                errors.append(v)

        if not unchanged:
            self.changed()

        if errors:
            raise WidgetsError(*errors)

        if not unchanged and self.context is self.adapted:
            publish(content, ObjectModifiedEvent(content))

        return unchanged

    def update(self):
        ...

        if Update in self.request:
            ...
            try:
                data = getWidgetsData(self, self.schema,
                                      strict=False,
                                      set_missing=True,
                                      names=self.fieldNames,
                                      exclude_readonly=True)

                unchanged = self.apply_update(data)
            except WidgetsError, errors:
                ...
            else:
                setUpEditWidgets(self, self.schema, force=1,
                                 names=self.fieldNames) # XXX Second setup
                # XXX Second setup: without content-parameter which is
                # equivalent to content = self.context (view.context)
                # compare default value _setUpWidget(...)
            ...
        return status

listing 2:
zope/app/form/utility.py

def setUpEditWidgets(view, schema, content=None, prefix=None, force=False,
                     names=None, context=None):
    ...
    _setUpWidgets(view, schema, content, prefix, force,
                  names, context, 'display', 'edit')

def _setUpWidgets(view, schema, content, prefix, force,
                  names, context, displayname, editname):
    ...

    if content is None:
        if context is None:
            content = view.context     # XXX here happens our
                                       # magic adapter-content-switch
        else:
            content = context

    ...