[Zope3-checkins] CVS: Zope3/src/zope/app/browser/form - add.py:1.18 editview.py:1.19

Jim Fulton jim@zope.com
Mon, 14 Apr 2003 04:27:46 -0400


Update of /cvs-repository/Zope3/src/zope/app/browser/form
In directory cvs.zope.org:/tmp/cvs-serv5417/browser/form

Modified Files:
	add.py editview.py 
Log Message:
Updated the form-genmeration software to support accessors. Mainly
this involved changing the software to use field ``get``, ``query``,
and ``set`` methods rather than attribute access.  Also modified the
tests to test accessor usage.

Fixed adapter support. Now edit views store the adapted context
separately from the context. Also, edit and add views use getApter
rather than queryAdapter to get adapters. The previous uses of
queryAdapter were hiding some logic errors.  Added unit tests!
In the course of adding unit tests, I discovered an issue relating to
event generation. Normally, we generate an ObjectModification event
when we edit something, however, it's not so clear what we should do
in the presense of an adapter. I finally decided that we should not
generate an event if the object was adapted. In that case, the adapter
should generate any necessary events.


=== Zope3/src/zope/app/browser/form/add.py 1.17 => 1.18 ===
--- Zope3/src/zope/app/browser/form/add.py:1.17	Thu Apr 10 02:17:34 2003
+++ Zope3/src/zope/app/browser/form/add.py	Mon Apr 14 04:27:15 2003
@@ -26,7 +26,7 @@
 from zope.configuration.action import Action
 from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
 from zope.security.checker import defineChecker, NamesChecker
-from zope.component import queryAdapter
+from zope.component import getAdapter
 from zope.component.view import provideView
 from zope.publisher.interfaces.browser import IBrowserPresentation
 from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
@@ -90,14 +90,15 @@
                 kw[str(name)] = data[name]
 
         content = self.create(*args, **kw)
-        adapted = queryAdapter(content, self.schema, content)
+        adapted = getAdapter(content, self.schema, context=self.context)
 
         errors = []
 
         for name in self._set_before_add:
             if name in data:
+                field = self.schema[name]
                 try:
-                    setattr(adapted, name, data[name])
+                    field.set(adapted, data[name])
                 except ValidationError:
                     errors.append(sys.exc_info()[1])
 
@@ -108,12 +109,13 @@
 
         content = self.add(content)
 
-        adapted = queryAdapter(content, self.schema, content)
+        adapted = getAdapter(content, self.schema)
 
         for name in self._set_after_add:
             if name in data:
+                field = self.schema[name]
                 try:
-                    setattr(adapted, name, data[name])
+                    field.set(adapted, data[name])
                 except ValidationError:
                     errors.append(sys.exc_info()[1])
 


=== Zope3/src/zope/app/browser/form/editview.py 1.18 => 1.19 ===
--- Zope3/src/zope/app/browser/form/editview.py:1.18	Fri Apr 11 18:15:45 2003
+++ Zope3/src/zope/app/browser/form/editview.py	Mon Apr 14 04:27:15 2003
@@ -26,7 +26,7 @@
 from zope.publisher.browser import BrowserView
 from zope.security.checker import defineChecker, NamesChecker
 from zope.component.view import provideView
-from zope.component import queryAdapter
+from zope.component import getAdapter
 
 from zope.app.interfaces.form import WidgetsError
 from zope.app.component.metaconfigure import resolveInterface
@@ -56,26 +56,18 @@
     fieldNames = property(lambda self: getFieldNamesInOrder(self.schema))
 
     def __init__(self, context, request):
-        # XXX   This feels like it should be 'getAdapter';  it won't really
-        #       be sensible to use an EditView against an object which
-        #       doesn't implement our schema.  The AddView subclass, however,
-        #       expects its context to be an IAdding, and doesn't use the
-        #       schema attributes to set values.
-        #
-        #       I originally had EditView declare an '_adaptContextToSchema'
-        #       method, which used 'getAdapter', and then overrode it in
-        #       AddView to just return the context.  That felt icky, too,
-        #       and was more complex, so I backed that out in favor of
-        #       just using 'queryAdapter'.
-        adapted = queryAdapter(context, self.schema)
-        if adapted is not None:
-            context = ContextWrapper(adapted, context, name='(adapted)')
         super(EditView, self).__init__(context, request)
+
         self._setUpWidgets()
 
 
     def _setUpWidgets(self):
-        setUpEditWidgets(self, self.schema, names=self.fieldNames)
+        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)
 
     def setPrefix(self, prefix):
         for widget in self.widgets():
@@ -94,12 +86,13 @@
         avoid tracking changes.
         """
 
-        content = self.context
+        content = self.adapted
 
         errors = []
         unchanged = True
 
         for name in data:
+            field = self.schema[name]
             try:
                 newvalue = data[name]
 
@@ -112,10 +105,10 @@
                 change = True
 
                 # Use self as a marker
-                change = getattr(content, name, self) != newvalue
+                change = field.query(content, self) != newvalue
 
                 if change:
-                    setattr(content, name, data[name])
+                    field.set(content, data[name])
                     unchanged = False
 
             except ValidationError, v:
@@ -124,7 +117,9 @@
         if errors:
             raise WidgetsError(*errors)
 
-        if not unchanged:
+        # We should not generate events whan an adapter is used. That's the
+        # adapter's job.
+        if not unchanged and self.context is self.adapted:
             publish(content, ObjectModifiedEvent(content))
 
         return unchanged