[Checkins] SVN: z3c.form/trunk/ - Feature: The ``applyChanges()`` function now returns a dictionary of changes

Stephan Richter srichter at cosmos.phy.tufts.edu
Mon Aug 13 09:47:11 EDT 2007


Log message for revision 78786:
  - Feature: The ``applyChanges()`` function now returns a dictionary of changes
    (grouped by interface) instead of a boolean. This allows us to generate a
    more detailed object-modified event. If no changes are applied, an empty
    dictionary is returned. The new behavior is compatible with the old one, so
    no changes to your code are required. (Thanks to Darryl Cousins for the
    request and implementation.)
  
  

Changed:
  U   z3c.form/trunk/CHANGES.txt
  U   z3c.form/trunk/src/z3c/form/form.py
  U   z3c.form/trunk/src/z3c/form/form.txt

-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt	2007-08-13 13:28:44 UTC (rev 78785)
+++ z3c.form/trunk/CHANGES.txt	2007-08-13 13:47:11 UTC (rev 78786)
@@ -5,6 +5,13 @@
 Version 1.6.0 (?/??/2007)
 -------------------------
 
+- Feature: The ``applyChanges()`` function now returns a dictionary of changes
+  (grouped by interface) instead of a boolean. This allows us to generate a
+  more detailed object-modified event. If no changes are applied, an empty
+  dictionary is returned. The new behavior is compatible with the old one, so
+  no changes to your code are required. (Thanks to Darryl Cousins for the
+  request and implementation.)
+
 - Feature: A new ``InvalidErrorViewSnippet`` class provides an error view
   snippet for ``zope.interface.Invalid`` exceptions, which are frequently used
   for invariants.

Modified: z3c.form/trunk/src/z3c/form/form.py
===================================================================
--- z3c.form/trunk/src/z3c/form/form.py	2007-08-13 13:28:44 UTC (rev 78785)
+++ z3c.form/trunk/src/z3c/form/form.py	2007-08-13 13:47:11 UTC (rev 78786)
@@ -32,7 +32,7 @@
 
 
 def applyChanges(form, content, data):
-    changed = False
+    changes = {}
     for name, field in form.fields.items():
         # If the field is not in the data, then go on to the next one
         if name not in data:
@@ -44,8 +44,9 @@
         # Only update the data, if it is different
         if dm.get() != data[name]:
             dm.set(data[name])
-            changed = True
-    return changed
+            # Record the change using information required later
+            changes.setdefault(dm.field.interface, []).append(name)
+    return changes
 
 
 def extends(*args, **kwargs):
@@ -206,11 +207,18 @@
 
     def applyChanges(self, data):
         content = self.getContent()
-        changed = applyChanges(self, content, data)
-        if changed:
+        changes = applyChanges(self, content, data)
+        # ``changes`` is a dictionary; if empty, there were no changes
+        if changes:
+            # Construct change-descriptions for the object-modified event
+            descriptions = []
+            for interface, names in changes.items():
+                descriptions.append(
+                    zope.lifecycleevent.Attributes(interface, *names))
+            # Send out a detailed object-modified event
             zope.event.notify(
-                zope.lifecycleevent.ObjectModifiedEvent(content))
-        return changed
+                zope.lifecycleevent.ObjectModifiedEvent(content, *descriptions))
+        return changes
 
     @button.buttonAndHandler(_('Apply'), name='apply')
     def handleApply(self, action):
@@ -218,8 +226,8 @@
         if errors:
             self.status = self.formErrorsMessage
             return
-        changed = self.applyChanges(data)
-        if changed:
+        changes = self.applyChanges(data)
+        if changes:
             self.status = self.successMessage
         else:
             self.status = self.noChangesMessage

Modified: z3c.form/trunk/src/z3c/form/form.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/form.txt	2007-08-13 13:28:44 UTC (rev 78785)
+++ z3c.form/trunk/src/z3c/form/form.txt	2007-08-13 13:47:11 UTC (rev 78786)
@@ -872,7 +872,43 @@
   >>> stephan.age
   27
 
+When an edit form is successfully committed, a detailed object-modified event
+is sent out telling the system about the changes. To see the error, let's
+create an event subscriber for object-modified events:
 
+  >>> eventlog = []
+  >>> import zope.lifecycleevent
+  >>> @zope.component.adapter(zope.lifecycleevent.ObjectModifiedEvent)
+  ... def logEvent(event):
+  ...     eventlog.append(event)
+  >>> zope.component.provideHandler(logEvent)
+
+Let's now submit the form again, successfully changing the age:
+
+  >>> request = TestRequest(form={
+  ...     'form.widgets.name': u'Claudia Richter',
+  ...     'form.widgets.gender': ['female'],
+  ...     'form.widgets.age': u'29',
+  ...     'form.buttons.apply': u'Apply'}
+  ...     )
+
+  >>> editForm = PersonEditForm(root[u'srichter'], request)
+  >>> addTemplate(editForm)
+  >>> editForm.update()
+
+We can now look at the event:
+
+  >>> event = eventlog[-1]
+  >>> event
+  <zope.app.event.objectevent.ObjectModifiedEvent object at ...>
+
+  >>> attrs = event.descriptions[0]
+  >>> attrs.interface
+  <InterfaceClass __builtin__.IPerson>
+  >>> attrs.attributes
+  ('age',)
+
+
 Successful Action with No Changes
 ---------------------------------
 
@@ -881,7 +917,7 @@
   >>> request = TestRequest(form={
   ...     'form.widgets.name': u'Claudia Richter',
   ...     'form.widgets.gender': ['female'],
-  ...     'form.widgets.age': u'27',
+  ...     'form.widgets.age': u'29',
   ...     'form.buttons.apply': u'Apply'}
   ...     )
 
@@ -1052,7 +1088,7 @@
       </div>
       <div class="row">
         <span id="form-widgets-age" class="text-widget int-field">
-          27
+          29
         </span>
       </div>
     </body>
@@ -1282,5 +1318,5 @@
   ...
   <input type="hidden" id="form-widgets-age"
          name="form.widgets.age" class="hidden-widget"
-         value="27" />
+         value="29" />
   ...



More information about the Checkins mailing list