[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