[Checkins] SVN: z3c.form/trunk/ - Feature: The `SequenceDataConverter` and `CollectionSequenceDataConverter`

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Sep 4 15:15:43 EDT 2008


Log message for revision 90822:
  - Feature: The `SequenceDataConverter` and `CollectionSequenceDataConverter`
    converter classes now ignore values that are not present in the terms when
    converting to a widget value.
  
  - Fixed test failure due to new I18n support.
  
  

Changed:
  U   z3c.form/trunk/CHANGES.txt
  U   z3c.form/trunk/src/z3c/form/browser/README.txt
  U   z3c.form/trunk/src/z3c/form/converter.py
  U   z3c.form/trunk/src/z3c/form/converter.txt
  U   z3c.form/trunk/src/z3c/form/widget.py

-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt	2008-09-04 18:40:58 UTC (rev 90821)
+++ z3c.form/trunk/CHANGES.txt	2008-09-04 19:15:42 UTC (rev 90822)
@@ -5,11 +5,12 @@
 Version 2.0.0 (2008-??-??)
 --------------------------
 
-- Feature: Add support for internationalization of z3c.form's messages,
-  add Russian translation. More translations are welcome.
+- Feature: The `SequenceDataConverter` and `CollectionSequenceDataConverter`
+  converter classes now ignore values that are not present in the terms when
+  converting to a widget value.
 
-- Bug: Use nocall: modifier in orderedselect_input.pt to avoid calling
-  list entry if it is callable.
+- Feature: Add support for internationalization of z3c.form's messages.
+  Added Russian translation.
 
 - Feature: The `TypeError` message used when a field does not provide
   ``IFormUnicode`` now also contains the type of the field.
@@ -23,6 +24,9 @@
   user interfaces.  The widget can be used for sequence fields (e.g. `IList`)
   that specify a simple value type field (e.g. `ITextLine` or `IInt`).
 
+- Bug: Use ``nocall:`` modifier in `orderedselect_input.pt` to avoid calling
+  list entry if it is callable.
+
 - Bug: Remove unused imports, adjust buildout dependencies in `setup.py`.
 
 

Modified: z3c.form/trunk/src/z3c/form/browser/README.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/browser/README.txt	2008-09-04 18:40:58 UTC (rev 90821)
+++ z3c.form/trunk/src/z3c/form/browser/README.txt	2008-09-04 19:15:42 UTC (rev 90822)
@@ -27,6 +27,12 @@
   >>> xmlconfig.XMLConfig('configure.zcml', zope.app.security)()
   >>> xmlconfig.XMLConfig('configure.zcml', z3c.form)()
 
+This utility is setup by hand, since its ZCML loads to many unwanted files:
+
+  >>> import zope.component
+  >>> import zope.i18n.negotiator
+  >>> zope.component.provideUtility(zope.i18n.negotiator.negotiator)
+
 also define a helper method for test the widgets:
 
   >>> from z3c.form import interfaces

Modified: z3c.form/trunk/src/z3c/form/converter.py
===================================================================
--- z3c.form/trunk/src/z3c/form/converter.py	2008-09-04 18:40:58 UTC (rev 90821)
+++ z3c.form/trunk/src/z3c/form/converter.py	2008-09-04 19:15:42 UTC (rev 90822)
@@ -255,7 +255,11 @@
             return []
         # Look up the term in the terms
         terms = widget.updateTerms()
-        return [terms.getTerm(value).token]
+        try:
+            return [terms.getTerm(value).token]
+        except LookupError, err:
+            # Swallow lookup errors, in case the options changed.
+            return []
 
     def toFieldValue(self, value):
         """See interfaces.IDataConverter"""
@@ -277,7 +281,14 @@
         widget = self.widget
         if widget.terms is None:
             widget.updateTerms()
-        return [widget.terms.getTerm(entry).token for entry in value]
+        values = []
+        for entry in value:
+            try:
+                values.append(widget.terms.getTerm(entry).token)
+            except LookupError, err:
+                # Swallow lookup errors, in case the options changed.
+                pass
+        return values
 
     def toFieldValue(self, value):
         """See interfaces.IDataConverter"""

Modified: z3c.form/trunk/src/z3c/form/converter.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/converter.txt	2008-09-04 18:40:58 UTC (rev 90821)
+++ z3c.form/trunk/src/z3c/form/converter.txt	2008-09-04 19:15:42 UTC (rev 90822)
@@ -506,7 +506,7 @@
   >>> sdv.toFieldValue(['m'])
   0
 
-Sometimes a field is not required. In those cases, the internalvalue is the
+Sometimes a field is not required. In those cases, the internal value is the
 missing value of the field. The converter interprets that as no value being
 selected:
 
@@ -515,6 +515,12 @@
   >>> sdv.toWidgetValue(gender.missing_value)
   []
 
+If the internal value is not a valid item in the terms, it is treated as
+missing:
+
+  >>> sdv.toWidgetValue(object())
+  []
+
 If "no value" has been specified in the widget, the missing value
 of the field is returned:
 
@@ -560,6 +566,19 @@
   >>> csdv.toFieldValue(['m'])
   [0]
 
+Of course, a collection field can also have multiple values:
+
+  >>> csdv.toWidgetValue([0, 1])
+  ['m', 'f']
+
+  >>> csdv.toFieldValue(['m', 'f'])
+  [0, 1]
+
+If any of the values are not a valid choice, they are simply ignored:
+
+  >>> csdv.toWidgetValue([0, 3])
+  ['m']
+
 For some field, like the ``Set``, the collection type is a tuple. Sigh. In
 these cases we use the last entry in the tuple as the type to use:
 

Modified: z3c.form/trunk/src/z3c/form/widget.py
===================================================================
--- z3c.form/trunk/src/z3c/form/widget.py	2008-09-04 18:40:58 UTC (rev 90821)
+++ z3c.form/trunk/src/z3c/form/widget.py	2008-09-04 19:15:42 UTC (rev 90822)
@@ -94,7 +94,7 @@
             if (interfaces.IContextAware.providedBy(self) and
                 not self.ignoreContext):
                 value = zope.component.getMultiAdapter(
-                    (self.context, self.field), 
+                    (self.context, self.field),
                     interfaces.IDataManager).query()
             # Step 1.2.2: If we still do not have a value, we can always use
             #             the default value of the field, id set
@@ -144,16 +144,16 @@
 
 class SequenceWidget(Widget):
     """Term based sequence widget base.
-    
+
     The sequence widget is used for select items from a sequence. Don't get
     confused, this widget does support to choose one or more values from a
-    sequence. The word sequence is not used for the schema field, it's used 
+    sequence. The word sequence is not used for the schema field, it's used
     for the values where this widget can choose from.
 
     This widget base class is used for build single or sequence values based
     on a sequence which is in most use case a collection. e.g.
     IList of IChoice for sequence values or IChoice for single values.
-    
+
     See also the MultiWidget for build sequence values based on none collection
     based values. e.g. IList of ITextLine
     """
@@ -213,23 +213,23 @@
 
 class MultiWidget(Widget):
     """None Term based sequence widget base.
-    
+
     The multi widget is used for ITuple or IList if no other widget is defined.
-    
+
     Some IList or ITuple are using another specialized widget if they can
     choose from a collection. e.g. a IList of IChoice. The base class of such
-    widget is the ISequenceWidget. 
-    
-    This widget can handle none collection based sequences and offers add or 
-    remove values to or from the sequence. Each sequence value get rendered by 
+    widget is the ISequenceWidget.
+
+    This widget can handle none collection based sequences and offers add or
+    remove values to or from the sequence. Each sequence value get rendered by
     it's own relevant widget. e.g. IList of ITextLine or ITuple of IInt
-    
+
     Each widget get rendered within a sequence value. This means each internal
     widget will repressent one value from the mutli widget value. Based on the
     nature of this (sub) widget setup the internal widget do not have a real
-    context and can't get binded to it. This makes it impossible to use a 
+    context and can't get binded to it. This makes it impossible to use a
     sequence of collection where the collection needs a context. But that
-    should not be a problem since sequence of collection will use the 
+    should not be a problem since sequence of collection will use the
     SequenceWidget as base.
     """
 
@@ -248,7 +248,7 @@
 
     @property
     def counterMarker(self):
-        # this get called in render from the template and contains always the 
+        # this get called in render from the template and contains always the
         # right amount of widgets we use.
         return '<input type="hidden" name="%s" value="%d" />' % (
             self.counterName, len(self.widgets))
@@ -274,12 +274,12 @@
 
     def applyValue(self, widget, value=interfaces.NOVALUE):
         """Validate and apply value to given widget.
-        
-        This method get called on any multi widget vaue change and is 
+
+        This method get called on any multi widget vaue change and is
         responsible for validate the given value and setup an error message.
-        
-        This is internal apply value and validation process is needed because 
-        nothing outside this mutli widget does know something about our 
+
+        This is internal apply value and validation process is needed because
+        nothing outside this mutli widget does know something about our
         internal sub widgets.
         """
         if value is not interfaces.NOVALUE:
@@ -337,10 +337,10 @@
         return property(get, set)
 
     def extract(self, default=interfaces.NOVALUE):
-        # This method is responsible to get the widgets value based on the 
+        # This method is responsible to get the widgets value based on the
         # request and nothing else.
-        # We have to setup the widgets for extract their values, because we 
-        # don't know how to do this for every field without the right widgets. 
+        # We have to setup the widgets for extract their values, because we
+        # don't know how to do this for every field without the right widgets.
         # Later we will setup the widgets based on this values. This is needed
         # because we probably set a new value in the fornm for our multi widget
         # which whould generate a different set of widgets.



More information about the Checkins mailing list