[Checkins] SVN: z3c.form/branches/icemac_validate_NOT_CHANGED/ fixed bug: `validator.SimpleFieldValidator` is now able to handle
Michael Howitz
mh at gocept.com
Sun May 17 09:18:11 EDT 2009
Log message for revision 100027:
fixed bug: `validator.SimpleFieldValidator` is now able to handle
`interfaces.NOT_CHANGED`. This value is set for file uploads when
the user did not choose a file for upload.
Thanks to Jacob Holm for the patch.
Changed:
U z3c.form/branches/icemac_validate_NOT_CHANGED/AUTHOR.txt
U z3c.form/branches/icemac_validate_NOT_CHANGED/CHANGES.txt
U z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.py
U z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.txt
-=-
Modified: z3c.form/branches/icemac_validate_NOT_CHANGED/AUTHOR.txt
===================================================================
--- z3c.form/branches/icemac_validate_NOT_CHANGED/AUTHOR.txt 2009-05-17 12:28:00 UTC (rev 100026)
+++ z3c.form/branches/icemac_validate_NOT_CHANGED/AUTHOR.txt 2009-05-17 13:18:11 UTC (rev 100027)
@@ -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/branches/icemac_validate_NOT_CHANGED/CHANGES.txt
===================================================================
--- z3c.form/branches/icemac_validate_NOT_CHANGED/CHANGES.txt 2009-05-17 12:28:00 UTC (rev 100026)
+++ z3c.form/branches/icemac_validate_NOT_CHANGED/CHANGES.txt 2009-05-17 13:18:11 UTC (rev 100027)
@@ -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/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.py
===================================================================
--- z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.py 2009-05-17 12:28:00 UTC (rev 100026)
+++ z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.py 2009-05-17 13:18:11 UTC (rev 100027)
@@ -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/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.txt
===================================================================
--- z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.txt 2009-05-17 12:28:00 UTC (rev 100026)
+++ z3c.form/branches/icemac_validate_NOT_CHANGED/src/z3c/form/validator.txt 2009-05-17 13:18:11 UTC (rev 100027)
@@ -79,9 +79,6 @@
... email = zope.schema.TextLine(
... title=u'E-mail')
...
- ... photo = zope.schema.Bytes(
- ... title=u'Photo')
- ...
... @zope.interface.invariant
... def isLoginPartOfEmail(person):
... if not person.email.startswith(person.login):
@@ -116,18 +113,10 @@
...
TooLong: (u'StephanCaveman3', 10)
-If the value has not changed, validation is successful:
-
- >>> from z3c.form import interfaces
- >>> simple_photo = validator.SimpleFieldValidator(
- ... None, None, None, IPerson['photo'], None)
- >>> simple_photo.validate(interfaces.NOT_CHANGED)
-
Let's now create a validator that also requires at least 1 numerical character
in the login name:
>>> import re
-
>>> class LoginValidator(validator.SimpleFieldValidator):
...
... def validate(self, value):
@@ -192,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