[Checkins] SVN: z3c.form/trunk/ Feature: Added ``IForm.ignoreRequiredOnValidation``, ``IWidgets.ignoreRequiredOnValidation``, ``IWidget.ignoreRequiredOnValidation``.

Adam Groszer cvs-admin at zope.org
Fri Aug 17 13:16:40 UTC 2012


Log message for revision 127515:
  Feature: Added ``IForm.ignoreRequiredOnValidation``,  ``IWidgets.ignoreRequiredOnValidation``,  ``IWidget.ignoreRequiredOnValidation``.

Changed:
  U   z3c.form/trunk/CHANGES.txt
  U   z3c.form/trunk/src/z3c/form/field.py
  U   z3c.form/trunk/src/z3c/form/field.txt
  U   z3c.form/trunk/src/z3c/form/form.py
  U   z3c.form/trunk/src/z3c/form/interfaces.py
  U   z3c.form/trunk/src/z3c/form/validator.py
  U   z3c.form/trunk/src/z3c/form/validator.txt
  U   z3c.form/trunk/src/z3c/form/widget.py

-=-
Modified: z3c.form/trunk/CHANGES.txt
===================================================================
--- z3c.form/trunk/CHANGES.txt	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/CHANGES.txt	2012-08-17 13:16:37 UTC (rev 127515)
@@ -5,7 +5,14 @@
 2.8.2 (unreleased)
 ------------------
 
-- ...
+- Feature: Added ``IForm.ignoreRequiredOnValidation``,
+  ``IWidgets.ignoreRequiredOnValidation``,
+  ``IWidget.ignoreRequiredOnValidation``.
+  Those enable ``extract`` and ``extractData`` to return without errors in
+  case a required field is not filled.
+  That also means the usual "Missing value" error will not get displayed.
+  But the ``required-info`` (usually the ``*``) yes.
+  This is handy to store partial state.
 
 
 2.8.1 (2012-08-06)

Modified: z3c.form/trunk/src/z3c/form/field.py
===================================================================
--- z3c.form/trunk/src/z3c/form/field.py	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/field.py	2012-08-17 13:16:37 UTC (rev 127515)
@@ -181,6 +181,7 @@
     ignoreContext = False
     ignoreRequest = False
     ignoreReadonly = False
+    ignoreRequiredOnExtract = False
     setErrors = True
 
     def __init__(self, form, request, content):
@@ -300,6 +301,7 @@
                 raw = widget.extract()
                 if raw is not interfaces.NO_VALUE:
                     value = interfaces.IDataConverter(widget).toFieldValue(raw)
+                widget.ignoreRequiredOnValidation = self.ignoreRequiredOnExtract
                 zope.component.getMultiAdapter(
                     (self.content,
                      self.request,

Modified: z3c.form/trunk/src/z3c/form/field.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/field.txt	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/field.txt	2012-08-17 13:16:37 UTC (rev 127515)
@@ -373,7 +373,9 @@
   ...
   ...     @zope.interface.invariant
   ...     def twiceAsLong(person):
-  ...         if len(person.lastName) >= 2 * len(person.firstName):
+  ...         # note: we're protecting here values against being None
+  ...         # just in case ignoreRequiredOnExtract lets that through
+  ...         if len(person.lastName or '') >= 2 * len(person.firstName or ''):
   ...             raise LastNameTooShort()
 
 Next we need a form that specifies the fields to be added:
@@ -767,6 +769,22 @@
   >>> manager.extract()
   ({'firstName': u'Stephan'}, (<ErrorViewSnippet for RequiredMissing>,))
 
+We can also turn off ``required`` checking for data extraction:
+
+  >>> request = TestRequest(form={
+  ...     'form.widgets.firstName': u'Stephan', 'form.widgets.id': u'srichter'})
+  >>> manager = field.FieldWidgets(personForm, request, context)
+  >>> manager.ignoreContext = True
+  >>> manager.ignoreRequiredOnExtract = True
+  >>> manager.update()
+
+Here we get the required field as ``None`` and no errors:
+
+  >>> manager.extract()
+  ({'lastName': None, 'firstName': u'Stephan'}, ())
+
+  >>> manager.ignoreRequiredOnExtract = False
+
 Or, we could violate a constraint. This constraint raises Invalid, which is
 a convenient way to raise errors where we mainly care about providing a custom
 error message.

Modified: z3c.form/trunk/src/z3c/form/form.py
===================================================================
--- z3c.form/trunk/src/z3c/form/form.py	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/form.py	2012-08-17 13:16:37 UTC (rev 127515)
@@ -112,12 +112,13 @@
     prefix = 'form.'
     status = ''
     template = None
-    widgets  = None
+    widgets = None
 
     mode = interfaces.INPUT_MODE
     ignoreContext = False
     ignoreRequest = False
     ignoreReadonly = False
+    ignoreRequiredOnExtract = False
 
     def getContent(self):
         '''See interfaces.IForm'''
@@ -142,6 +143,7 @@
     def extractData(self, setErrors=True):
         '''See interfaces.IForm'''
         self.widgets.setErrors = setErrors
+        self.widgets.ignoreRequiredOnExtract = self.ignoreRequiredOnExtract
         return self.widgets.extract()
 
     def update(self):

Modified: z3c.form/trunk/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/trunk/src/z3c/form/interfaces.py	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/interfaces.py	2012-08-17 13:16:37 UTC (rev 127515)
@@ -383,7 +383,7 @@
 
 class IWidgetLayoutTemplate(zope.interface.Interface):
     """Widget layout template marker used for render the widget layout.
-    
+
     It is important that we don't inherit this template from IPageTemplate.
     otherwise we will get into trouble since we lookup an IPageTemplate
     in the widget/render method.
@@ -446,7 +446,7 @@
         default=False,
         required=False)
 
-    #ugly thing to remove setErrors parameter from extract
+    # ugly thing to remove setErrors parameter from extract
     setErrors = zope.schema.Bool(
         title=_('Set errors'),
         description=_('A flag, when set, the widget sets error messages '
@@ -454,6 +454,15 @@
         default=True,
         required=False)
 
+    # a bit different from ignoreRequiredOnExtract, because we record
+    # here the fact, but for IValidator, because the check happens there
+    ignoreRequiredOnValidation = zope.schema.Bool(
+        title=_('Ignore Required validation'),
+        description=_("If set then required fields will pass validation "
+                      "regardless whether they're filled in or not"),
+        default=False,
+        required=True)
+
     showDefault = zope.schema.Bool(
         title=_('Show default value'),
         description=_('A flag, when set, makes the widget to display'
@@ -639,6 +648,13 @@
         default=False,
         required=True)
 
+    ignoreRequiredOnExtract = zope.schema.Bool(
+        title=_('Ignore Required validation on extract'),
+        description=_("If set then required fields will pass validation "
+                      "on extract regardless whether they're filled in or not"),
+        default=False,
+        required=True)
+
     hasRequiredFields = zope.schema.Bool(
         title=_('Has required fields'),
         description=_('A flag set when at least one field is marked as '
@@ -902,6 +918,13 @@
         default=False,
         required=True)
 
+    ignoreRequiredOnExtract = zope.schema.Bool(
+        title=_('Ignore Required validation on extract'),
+        description=_("If set then required fields will pass validation "
+                      "on extract regardless whether they're filled in or not"),
+        default=False,
+        required=True)
+
     widgets = zope.schema.Object(
         title=_('Widgets'),
         description=_('A widget manager containing the widgets to be used in '

Modified: z3c.form/trunk/src/z3c/form/validator.py
===================================================================
--- z3c.form/trunk/src/z3c/form/validator.py	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/validator.py	2012-08-17 13:16:37 UTC (rev 127515)
@@ -16,6 +16,9 @@
 $Id$
 """
 __docformat__ = "reStructuredText"
+
+import copy
+
 import zope.component
 import zope.interface
 import zope.schema
@@ -45,6 +48,10 @@
         context = self.context
         field = self.field
         widget = self.widget
+        if field.required and widget and widget.ignoreRequiredOnValidation:
+            # make the field not-required while checking
+            field = copy.copy(field)
+            field.required = False
         if context is not None:
             field = field.bind(context)
         if value is interfaces.NOT_CHANGED:

Modified: z3c.form/trunk/src/z3c/form/validator.txt
===================================================================
--- z3c.form/trunk/src/z3c/form/validator.txt	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/validator.txt	2012-08-17 13:16:37 UTC (rev 127515)
@@ -300,6 +300,50 @@
   True
 
 
+Ignoring required
+~~~~~~~~~~~~~~~~~
+
+Sometimes we want to ignore ``required`` checking.
+That's because we want to have *all* fields extracted from the form
+regardless whether required fields are filled.
+And have no required-errors displayed.
+
+  >>> class IPersonRequired(zope.interface.Interface):
+  ...     login = zope.schema.TextLine(
+  ...         title=u'Login',
+  ...         required=True)
+  ...
+  ...     email = zope.schema.TextLine(
+  ...         title=u'E-mail')
+
+  >>> simple = validator.SimpleFieldValidator(
+  ...     None, None, None, IPersonRequired['login'], None)
+
+  >>> simple.validate(None)
+  Traceback (most recent call last):
+  ...
+  RequiredMissing: login
+
+Ooops we need a widget too.
+
+  >>> widget = z3c.form.widget.Widget(None)
+  >>> widget.field = IPersonRequired['login']
+
+  >>> simple = validator.SimpleFieldValidator(
+  ...     None, None, None, IPersonRequired['login'], widget)
+
+  >>> simple.validate(None)
+  Traceback (most recent call last):
+  ...
+  RequiredMissing: login
+
+Meeeh, need to signal that we need to ignore ``required``:
+
+  >>> widget.ignoreRequiredOnValidation = True
+
+  >>> simple.validate(None)
+
+
 Widget Manager Validators
 -------------------------
 
@@ -463,4 +507,3 @@
   'Invalid'
   >>> errors[0].args[0]
   'The login not part of email.'
-

Modified: z3c.form/trunk/src/z3c/form/widget.py
===================================================================
--- z3c.form/trunk/src/z3c/form/widget.py	2012-08-17 13:11:02 UTC (rev 127514)
+++ z3c.form/trunk/src/z3c/form/widget.py	2012-08-17 13:16:37 UTC (rev 127515)
@@ -53,6 +53,8 @@
     template = None
     layout = None
     ignoreRequest = FieldProperty(interfaces.IWidget['ignoreRequest'])
+    ignoreRequiredOnValidation = FieldProperty(
+        interfaces.IWidget['ignoreRequiredOnValidation'])
     setErrors = FieldProperty(interfaces.IWidget['setErrors'])
     showDefault = FieldProperty(interfaces.IWidget['showDefault'])
 



More information about the checkins mailing list