[Checkins] SVN: z3c.form/trunk/ merged branch icemac_validate_NOT_CHANGED

Michael Howitz mh at gocept.com
Sun May 17 09:21:19 EDT 2009


Log message for revision 100028:
  merged branch icemac_validate_NOT_CHANGED
  

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

-=-
Modified: z3c.form/trunk/AUTHOR.txt
===================================================================
--- z3c.form/trunk/AUTHOR.txt	2009-05-17 13:18:11 UTC (rev 100027)
+++ z3c.form/trunk/AUTHOR.txt	2009-05-17 13:21:18 UTC (rev 100028)
@@ -11,10 +11,11 @@
 Daniel Nouri
 Darryl Cousins
 Herman Himmelbauer
+Jacob Holm
 Laurent Mignon
 Malthe Borch
 Marius Gedminas
 Martijn Faassen
 Michael Howitz
 Michael Kerrin
-Paul Carduner
+Paul Carduner
\ No newline at end of file

Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt	2009-05-17 13:18:11 UTC (rev 100027)
+++ z3c.form/trunk/CHANGES.txt	2009-05-17 13:21:18 UTC (rev 100028)
@@ -150,7 +150,11 @@
 
 - Bug: Don't cause warnings in Python 2.6.
 
+- Bug: `validator.SimpleFieldValidator` is now able to handle
+  `interfaces.NOT_CHANGED`. This value is set for file uploads when
+  the user does not choose a file for upload.
 
+
 Version 1.9.0 (2008-08-26)
 --------------------------
 

Modified: z3c.form/trunk/src/z3c/form/validator.py
===================================================================
--- z3c.form/trunk/src/z3c/form/validator.py	2009-05-17 13:18:11 UTC (rev 100027)
+++ z3c.form/trunk/src/z3c/form/validator.py	2009-05-17 13:21:18 UTC (rev 100028)
@@ -42,9 +42,28 @@
 
     def validate(self, value):
         """See interfaces.IValidator"""
+        context = self.context
         field = self.field
-        if self.context is not None:
-            field = field.bind(self.context)
+        widget = self.widget
+        if context is not None:
+            field = field.bind(context)
+        if value is interfaces.NOT_CHANGED:
+            if (interfaces.IContextAware.providedBy(widget) and
+                not widget.ignoreContext):
+                # get value from context
+                value = zope.component.getMultiAdapter(
+                    (context, field),
+                    interfaces.IDataManager).query()
+            else:
+                value = interfaces.NO_VALUE
+            if value is interfaces.NO_VALUE:
+                # look up default value
+                value = field.default
+                adapter = zope.component.queryMultiAdapter(
+                    (context, self.request, self.view, field, widget),
+                    interfaces.IValue, name='default')
+                if adapter:
+                    value = adapter.get()
         return field.validate(value)
 
     def __repr__(self):

Modified: z3c.form/trunk/src/z3c/form/validator.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/validator.txt	2009-05-17 13:18:11 UTC (rev 100027)
+++ z3c.form/trunk/src/z3c/form/validator.txt	2009-05-17 13:21:18 UTC (rev 100028)
@@ -117,7 +117,6 @@
 in the login name:
 
   >>> import re
-
   >>> class LoginValidator(validator.SimpleFieldValidator):
   ...
   ...     def validate(self, value):
@@ -182,7 +181,125 @@
   ...     (None, None, None, IPerson['email'], None),
   ...     interfaces.IValidator)
 
+Widget Validators and File-Uploads
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+File-Uploads behave a bit different than the other form
+elements. Whether the user did not choose a file to upload
+``interfaces.NOT_CHANGED`` is set as value. But the validator knows
+how to handle this.
+
+The example has two bytes fields where File-Uploads are possible, one
+field is required the other one not:
+
+  >>> class IPhoto(zope.interface.Interface):
+  ...     data = zope.schema.Bytes(
+  ...         title=u'Photo')
+  ...
+  ...     thumb = zope.schema.Bytes(
+  ...         title=u'Thumbnail',
+  ...         required=False)
+
+There are several possible cases to differentiate between:
+
+No widget
++++++++++
+
+If there is no widget or the widget does not provide
+``interfaces.IContextAware``, no value is looked up from the
+context. So the not required field validates successfully but the
+required one has an required missing error, as the default value of
+the field is looked up on the field:
+
+  >>> simple_thumb = validator.SimpleFieldValidator(
+  ...     None, None, None, IPhoto['thumb'], None)
+  >>> simple_thumb.validate(interfaces.NOT_CHANGED)
+
+  >>> simple_data = validator.SimpleFieldValidator(
+  ...     None, None, None, IPhoto['data'], None)
+  >>> simple_data.validate(interfaces.NOT_CHANGED)
+  Traceback (most recent call last):
+  RequiredMissing
+
+Widget which ignores context
+++++++++++++++++++++++++++++
+
+If the context is ignored in the widget - as in the add form - the
+behavior is the same as if there was no widget:
+
+  >>> import z3c.form.widget
+  >>> widget = z3c.form.widget.Widget(None)
+  >>> zope.interface.alsoProvides(widget, interfaces.IContextAware)
+  >>> widget.ignoreContext = True
+  >>> simple_thumb = validator.SimpleFieldValidator(
+  ...     None, None, None, IPhoto['thumb'], widget)
+  >>> simple_thumb.validate(interfaces.NOT_CHANGED)
+
+  >>> simple_data = validator.SimpleFieldValidator(
+  ...     None, None, None, IPhoto['data'], widget)
+  >>> simple_data.validate(interfaces.NOT_CHANGED)
+  Traceback (most recent call last):
+  RequiredMissing
+
+Look up value from default adapter
+++++++++++++++++++++++++++++++++++
+
+When the value is ``interfaces.NOT_CHANGED`` the validator tries to
+look up the default value using a ``interfaces.IValue``
+adapter. Whether the adapter is found, its value is used as default,
+so the validation of the required field is successful here:
+
+  >>> data_default = z3c.form.widget.StaticWidgetAttribute(
+  ...     'data', context=None, request=None, view=None,
+  ...     field=IPhoto['data'], widget=widget)
+  >>> zope.component.provideAdapter(data_default, name='default')
+  >>> simple_data.validate(interfaces.NOT_CHANGED)
+
+
+Look up value from context
+++++++++++++++++++++++++++
+
+If there is a context aware widget which does not ignore its context,
+the value is looked up on the context using a data manager:
+
+  >>> class Photo(object):
+  ...     zope.interface.implements(IPhoto)
+  ...
+  ...     data = None
+  ...     thumb = None
+  >>> photo = Photo()
+  >>> widget.ignoreContext = False
+  >>> zope.component.provideAdapter(z3c.form.datamanager.AttributeField)
+
+  >>> simple_thumb = validator.SimpleFieldValidator(
+  ...     photo, None, None, IPhoto['thumb'], widget)
+  >>> simple_thumb.validate(interfaces.NOT_CHANGED)
+
+If the value is not set on the context it is a required missing as
+neither context nor input have a valid value:
+
+  >>> simple_data = validator.SimpleFieldValidator(
+  ...     photo, None, None, IPhoto['data'], widget)
+  >>> simple_data.validate(interfaces.NOT_CHANGED)
+  Traceback (most recent call last):
+  RequiredMissing
+
+After setting the value validation is successful:
+
+  >>> photo.data = 'data'
+  >>> simple_data.validate(interfaces.NOT_CHANGED)
+
+
+Clean-up
+++++++++
+
+  >>> gsm = zope.component.getGlobalSiteManager()
+  >>> gsm.unregisterAdapter(z3c.form.datamanager.AttributeField)
+  True
+  >>> gsm.unregisterAdapter(data_default, name='default')
+  True
+
+
 Widget Manager Validators
 -------------------------
 



More information about the Checkins mailing list