[Checkins] SVN: z3c.form/branches/adamg-missing-terms/src/z3c/form/ next stab on accepting missing vocabulary terms
Adam Groszer
cvs-admin at zope.org
Fri Sep 7 08:31:35 UTC 2012
Log message for revision 127760:
next stab on accepting missing vocabulary terms
Changed:
U z3c.form/branches/adamg-missing-terms/src/z3c/form/configure.zcml
U z3c.form/branches/adamg-missing-terms/src/z3c/form/form.py
U z3c.form/branches/adamg-missing-terms/src/z3c/form/interfaces.py
U z3c.form/branches/adamg-missing-terms/src/z3c/form/term.py
U z3c.form/branches/adamg-missing-terms/src/z3c/form/util.py
U z3c.form/branches/adamg-missing-terms/src/z3c/form/util.txt
U z3c.form/branches/adamg-missing-terms/src/z3c/form/validator.py
-=-
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/configure.zcml 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/configure.zcml 2012-09-07 08:31:30 UTC (rev 127760)
@@ -83,9 +83,9 @@
<adapter
factory=".term.ChoiceTerms"
/>
- <adapter
+ <!--<adapter
factory=".term.ChoiceTermsVocabulary"
- />
+ />-->
<adapter
factory=".term.MissingChoiceTermsVocabulary"
/>
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/form.py
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/form.py 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/form.py 2012-09-07 08:31:30 UTC (rev 127760)
@@ -34,22 +34,19 @@
changes = {}
for name, field in form.fields.items():
# If the field is not in the data, then go on to the next one
- if name not in data:
+ try:
+ newValue = data[name]
+ except KeyError:
continue
# If the value is NOT_CHANGED, ignore it, since the widget/converter
# sent a strong message not to do so.
- if data[name] is interfaces.NOT_CHANGED:
+ if newValue is interfaces.NOT_CHANGED:
continue
- # Get the datamanager and get the original value
- dm = zope.component.getMultiAdapter(
- (content, field.field), interfaces.IDataManager)
- # Only update the data, if it is different
- # Or we can not get the original value, in which case we can not check
- # Or it is an Object, in case we'll never know
- if (not dm.canAccess() or
- dm.query() != data[name] or
- zope.schema.interfaces.IObject.providedBy(field.field)):
- dm.set(data[name])
+ if util.changedField(field.field, newValue, context=content):
+ # Only update the data, if it is different
+ dm = zope.component.getMultiAdapter(
+ (content, field.field), interfaces.IDataManager)
+ dm.set(newValue)
# Record the change using information required later
changes.setdefault(dm.field.interface, []).append(name)
return changes
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/interfaces.py 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/interfaces.py 2012-09-07 08:31:30 UTC (rev 127760)
@@ -1111,18 +1111,3 @@
class IAfterWidgetUpdateEvent(IWidgetEvent):
"""An event sent out after the widget was updated."""
-
-
-
-class IForgivingChoice(zope.schema.interfaces.IChoice):
- pass
-
-class ForgivingChoice(zope.schema.Choice):
- zope.interface.implements(IForgivingChoice)
-
- def _validate(self, value):
- if self.context is not None:
- if self.query(self.context) == value:
- return
-
- super(ForgivingChoice, self)._validate(value)
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/term.py
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/term.py 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/term.py 2012-09-07 08:31:30 UTC (rev 127760)
@@ -22,6 +22,7 @@
from zope.schema import vocabulary
from z3c.form import interfaces
+from z3c.form import util
from z3c.form.i18n import MessageFactory as _
@@ -135,14 +136,13 @@
return self.makeMissingTerm(value)
def makeToken(self, value):
- return unicode(value).encode('utf8').encode('base64').strip()
+ # create a unique valid ASCII token
+ return util.createCSSId(unicode(value))
- def makeMissingTerm(self, value, token=None):
+ def makeMissingTerm(self, value):
"""Return a term that should be displayed for the missing token or
raise LookupError if it's really invalid"""
- if token is None:
- token = self.makeToken(value)
- return vocabulary.SimpleTerm(value, token,
+ return vocabulary.SimpleTerm(value, self.makeToken(value),
title=_(u'Missing: ${value}', mapping=dict(value=unicode(value))))
def getTermByToken(self, token):
@@ -154,7 +154,12 @@
value = zope.component.getMultiAdapter(
(self.widget.context, self.widget.field),
interfaces.IDataManager).query()
- return self.makeMissingTerm(value, token=token)
+ term = self.makeMissingTerm(value)
+ if term.token == token:
+ # check if the given token matches the value, if not
+ # fall back on LookupError, otherwise we might accept
+ # any crap coming from the request
+ return term
raise LookupError(token)
@@ -163,15 +168,7 @@
"""ITerms adapter for zope.schema.IChoice based implementations using
vocabulary with missing terms support"""
- zope.component.adapts(
- zope.interface.Interface,
- interfaces.IFormLayer,
- zope.interface.Interface,
- interfaces.IForgivingChoice,
- zope.schema.interfaces.IBaseVocabulary,
- interfaces.IWidget)
-
class ChoiceTermsSource(SourceTerms):
"ITerms adapter for zope.schema.IChoice based implementations using source."
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/util.py
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/util.py 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/util.py 2012-09-07 08:31:30 UTC (rev 127760)
@@ -21,6 +21,7 @@
import string
import zope.interface
import zope.contenttype
+import zope.schema
from z3c.form import interfaces
from z3c.form.i18n import MessageFactory as _
@@ -28,12 +29,16 @@
_identifier = re.compile('[A-Za-z][a-zA-Z0-9_]*$')
+
def createId(name):
if _identifier.match(name):
return str(name).lower()
return name.encode('utf-8').encode('hex')
+
_acceptableChars = string.letters + string.digits + '_-'
+
+
def createCSSId(name):
return str(''.join([((char in _acceptableChars and char) or
char.encode('utf-8').encode('hex'))
@@ -41,6 +46,7 @@
classTypes = type, types.ClassType
+
def getSpecification(spec, force=False):
"""Get the specification of the given object.
@@ -128,6 +134,41 @@
return widget.filename
+def changedField(field, value, context=None):
+ """Figure if a field's value changed
+
+ Comparing the value of the context attribute and the given value"""
+ if context is None:
+ context = field.context
+
+ # Get the datamanager and get the original value
+ dm = zope.component.getMultiAdapter(
+ (context, field), interfaces.IDataManager)
+ # now figure value chaged status
+ # Or we can not get the original value, in which case we can not check
+ # Or it is an Object, in case we'll never know
+ if (not dm.canAccess() or
+ dm.query() != value or
+ zope.schema.interfaces.IObject.providedBy(field)):
+ return True
+ else:
+ return False
+
+
+def changedWidget(widget, value, field=None):
+ """figure if a widget's value changed
+
+ Comparing the value of the widget context attribute and the given value"""
+ if (interfaces.IContextAware.providedBy(widget)
+ and not widget.ignoreContext):
+ # if the widget is context aware, figure if it's field changed
+ if field is None:
+ field = widget.field
+ return changedField(field, value)
+ # otherwise we cannot, return 'always changed'
+ return True
+
+
class UniqueOrderedKeys(object):
"""Ensures that we only use unique keys in a list.
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/util.txt
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/util.txt 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/util.txt 2012-09-07 08:31:30 UTC (rev 127760)
@@ -46,7 +46,10 @@
>>> util.createCSSId(u'This has spaces')
'This20has20spaces'
+ >>> util.createCSSId(unicode(dict({1:'x', 'foobar': 42})))
+ '7b13a2027x272c2027foobar273a20427d'
+
``getWidgetById(form, id)`` Function
------------------------------------
Modified: z3c.form/branches/adamg-missing-terms/src/z3c/form/validator.py
===================================================================
--- z3c.form/branches/adamg-missing-terms/src/z3c/form/validator.py 2012-09-07 06:57:57 UTC (rev 127759)
+++ z3c.form/branches/adamg-missing-terms/src/z3c/form/validator.py 2012-09-07 08:31:30 UTC (rev 127760)
@@ -45,6 +45,10 @@
def validate(self, value):
"""See interfaces.IValidator"""
+ if value is interfaces.NOT_CHANGED:
+ # no need to validate unchanged values
+ return True
+
context = self.context
field = self.field
widget = self.widget
@@ -54,23 +58,10 @@
field.required = False
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()
+
+ if widget and not util.changedWidget(widget, value, field=field):
+ # if new value == old value, no need to validate
+ return True
return field.validate(value)
def __repr__(self):
More information about the checkins
mailing list