[Checkins] SVN: z3c.form/branches/adamg-objectwidget/src/z3c/form/ finish off the day,

Adam Groszer agroszer at gmail.com
Tue Oct 7 14:32:13 EDT 2008


Log message for revision 91878:
  finish off the day,
  factory is solved
  multi-error is in sight
  code cleanup needed
  

Changed:
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/converter.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py
  U   z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py
  A   z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py

-=-
Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -3,66 +3,12 @@
 import zope.interface
 import zope.schema.interfaces
 
-from z3c.form import action, button, form, interfaces
-from z3c.form.i18n import MessageFactory as _
-from z3c.form import interfaces
+from z3c.form import form, interfaces
 from z3c.form.widget import Widget, FieldWidget
-from z3c.form.field import FieldWidgets, Fields
 from z3c.form.browser import widget
-from z3c.form.subform import EditSubForm
 
-class ObjectSubForm(form.BaseForm):
-    zope.interface.implements(interfaces.ISubForm)
+from z3c.form.object import ObjectSubForm
 
-    formErrorsMessage = _('There were some errors.')
-    successMessage = _('Data successfully updated.')
-    noChangesMessage = _('No changes were applied.')
-
-    def __init__(self, context, parentWidget):
-        self.context = context
-        self.request = parentWidget.request
-        self.parentWidget = parentWidget
-        self.parentForm = self.__parent__ = parentWidget.form
-
-    def _validate(self):
-        for widget in self.widgets.values():
-            try:
-                # convert widget value to field value
-                converter = interfaces.IDataConverter(widget)
-                value = converter.toFieldValue(widget.value)
-                # validate field value
-                zope.component.getMultiAdapter(
-                    (self.context,
-                     self.request,
-                     self.parentWidget.form,
-                     getattr(widget, 'field', None),
-                     widget),
-                    interfaces.IValidator).validate(value)
-            except (zope.schema.ValidationError, ValueError), error:
-                # on exception, setup the widget error message
-                view = zope.component.getMultiAdapter(
-                    (error, self.request, widget, widget.field,
-                     self.parentWidget.form, self.context),
-                    interfaces.IErrorViewSnippet)
-                view.update()
-                widget.error = view
-
-    def update(self):
-        self.fields = Fields(self.parentWidget.field.schema)
-
-        self.mode = self.parentWidget.mode
-        self.ignoreContext = self.parentWidget.ignoreContext
-        self.ignoreRequest = self.parentWidget.ignoreRequest
-        self.prefix = self.parentWidget.field.__name__
-
-        if interfaces.IFormAware.providedBy(self.parentWidget):
-            self.ignoreReadonly = self.parentWidget.form.ignoreReadonly
-
-        super(ObjectSubForm, self).update()
-
-        self._validate()
-
-
 class ObjectWidget(widget.HTMLFormElement, Widget):
     zope.interface.implementsOnly(interfaces.IObjectWidget)
 

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/browser/object.txt	2008-10-07 18:32:12 UTC (rev 91878)
@@ -18,6 +18,15 @@
 
 
 
+  >>> from z3c.form.dummy import MySubObjectFactory
+  >>> from z3c.form.dummy import MySecondFactory
+
+  >>> import zope.component
+
+  >>> zope.component.provideAdapter(MySubObjectFactory, name='IMySubObject')
+  >>> zope.component.provideAdapter(MySecondFactory, name='IMySecond')
+
+
 As for all widgets, the objectwidget must provide the new ``IWidget``
 interface:
 
@@ -184,8 +193,8 @@
 We have to provide an adapter first:
 
   >>> zope.component.provideAdapter(object.ObjectFieldWidget)
-  >>> from z3c.form import converter
-  >>> zope.component.provideAdapter(converter.ObjectConverter)
+  >>> import z3c.form.object
+  >>> zope.component.provideAdapter(z3c.form.object.ObjectConverter)
 
 We define an interface containing a subobject, and an addform for it:
 
@@ -222,7 +231,7 @@
 and which is already updated:
 
   >>> myaddform.widgets['subobject'].subform
-  <z3c.form.browser.object.ObjectSubForm object at ...>
+  <z3c.form.object.ObjectSubForm object at ...>
   >>> myaddform.widgets['subobject'].subform.widgets.keys()
   ['foofield', 'barfield']
 
@@ -428,3 +437,61 @@
 
   >>> root['first'].subobject.barfield
   55
+
+
+
+  >>> request = TestRequest(form={'subobject.widgets.foofield':u'999999',
+  ...                             'subobject.widgets.barfield':u'bad',
+  ...                             'form.widgets.name':u'first',
+  ...                             'form.widgets.subobject-empty-marker':u'1',
+  ...                             'form.buttons.apply':'Apply'})
+
+  >>> editform.request = request
+
+#>>> from pub.dbgpclient import brk; brk('192.168.32.1')
+
+  >>> editform.update()
+  >>> print editform.render()
+  <html xmlns="http://www.w3.org/1999/xhtml">
+    <body>
+      <i>There were some errors.</i>
+      <ul>
+        <li>
+        my object:
+          <div class="error">The entered value is not a valid integer literal.</div>
+        </li>
+      </ul>
+      <form action=".">
+        <div class="row">
+          <b>
+            <div class="error">The entered value is not a valid integer literal.</div>
+          </b>
+          <label for="form-widgets-subobject">my object</label>
+          <fieldset class="object-widget required" id="form-widgets-subobject" name="form.widgets.subobject">
+            <legend>my object</legend>
+            <input class="text-widget required int-field" id="subobject-widgets-foofield" name="subobject.widgets.foofield" type="text" value="badder">
+            <br>
+            <div class="error">
+              <div class="error">The entered value is not a valid integer literal.</div>
+            </div>
+            <input class="text-widget required int-field" id="subobject-widgets-barfield" name="subobject.widgets.barfield" type="text" value="bad">
+            <br>
+            <input name="form.widgets.subobject-empty-marker" type="hidden" value="1">
+          </fieldset>
+        </div>
+        <div class="row">
+          <label for="form-widgets-name">name</label>
+          <input class="text-widget required textline-field" id="form-widgets-name" name="form.widgets.name" type="text" value="first">
+        </div>
+        <div class="action">
+          <input class="submit-widget button-field" id="form-buttons-apply" name="form.buttons.apply" type="submit" value="Apply">
+        </div>
+      </form>
+    </body>
+  </html>
+
+  >>> root['first'].subobject.foofield
+  43
+
+  >>> root['first'].subobject.barfield
+  55

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/configure.zcml	2008-10-07 18:32:12 UTC (rev 91878)
@@ -75,7 +75,7 @@
       factory=".converter.MultiConverter"
       />
   <adapter
-      factory=".converter.ObjectConverter"
+      factory=".object.ObjectConverter"
       />
 
   <!-- ITerms -->

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/converter.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/converter.py	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/converter.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -362,67 +362,7 @@
         # convert the field values to a tuple or list
         return collectionType(values)
 
-from z3c.form.dummy import MySubObject
 
-class ObjectConverter(BaseDataConverter):
-    """Data converter for IObjectWidget."""
-
-    zope.component.adapts(
-        zope.schema.interfaces.IObject, interfaces.IObjectWidget)
-
-    factory = MySubObject
-    #factory = None
-
-    def _fields(self):
-        x = zope.schema.getFields(self.field.schema)
-        return x
-
-    def toWidgetValue(self, value):
-        """Just dispatch it."""
-        if value is self.field.missing_value:
-            return None
-
-        return value
-
-        rv = {}
-        for name, field in self._fields().items():
-            #widget = zope.component.getMultiAdapter((field, self.widget.request),
-            #    interfaces.IFieldWidget)
-            #converter = zope.component.getMultiAdapter((field, widget),
-            #    interfaces.IDataConverter)
-
-            v = getattr(value, name, None)
-            #rv[name] = converter.toWidgetValue(v)
-            rv[name] = v
-
-        return (rv, tuple())
-
-    def toFieldValue(self, value):
-        """See interfaces.IDataConverter"""
-        #if self.factory is None:
-        #    adapter = zope.component.queryMultiAdapter(
-        #        (self.widget.context, self.widget.request, self.widget.form,
-        #         self.field.schema, self.widget),
-        #        interfaces.IValue, name='default')
-        #    if adapter:
-        #        obj = adapter.get()
-        #else:
-        #    obj = self.factory()
-
-        #this is creepy
-        if value[1]:
-            raise value[1][0].error
-        
-        obj = self.factory()
-        for name, f in self._fields().items():
-            try:
-                setattr(obj, name, value[0][name])
-            except KeyError:
-                #smells like an input error?
-                pass
-        return obj
-
-
 class BoolSingleCheckboxDataConverter(BaseDataConverter):
     "A special converter between boolean fields and single checkbox widgets."
 

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/dummy.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -7,7 +7,8 @@
 from zope.schema.fieldproperty import FieldProperty
 
 class IMySubObject(zope.interface.Interface):
-    foofield = zope.schema.Int(default=1111)
+    foofield = zope.schema.Int(default=1111,
+                               max=9999)
     barfield = zope.schema.Int(default=2222)
 
 class MySubObject(object):
@@ -43,38 +44,59 @@
 import zope.schema.interfaces
 
 from z3c.form import interfaces
+from z3c.form.object import IObjectFactory
 
-
 class FactoryAdapter(object):
     """ """
 
-    zope.interface.implements(interfaces.IValue)
+    zope.interface.implements(IObjectFactory)
     zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, zope.schema.interfaces.IField, interfaces.IWidget)
+        interfaces.IForm, interfaces.IWidget)
 
     factory = None
 
-    def __init__(self, context, request, form, field, widget):
+    def __init__(self, context, request, form, widget):
         self.context = context
         self.request = request
         self.form = form
-        self.field = field
         self.widget = widget
 
-    def get(self):
+    def get(self, value):
         return self.factory()
 
     def __repr__(self):
         return '<%s %r>' % (self.__class__.__name__, self.__name__)
 
+#class MySubObjectFactory(FactoryAdapter):
+#    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+#        interfaces.IForm, zope.interface.Interface, interfaces.IWidget)
+#    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+#    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
+#
+#    factory = MySubObject
+#
+#class MySecondFactory(FactoryAdapter):
+#    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+#        interfaces.IForm, zope.interface.Interface, interfaces.IWidget)
+#    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+#    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
+#
+#    factory = MySecond
+
 class MySubObjectFactory(FactoryAdapter):
-    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, IMySubObject, interfaces.IWidget)
+    zope.component.adapts(
+        zope.interface.Interface, interfaces.IFormLayer,
+        interfaces.IForm, interfaces.IWidget)
+    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
 
     factory = MySubObject
 
 class MySecondFactory(FactoryAdapter):
-    zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
-        interfaces.IForm, IMySecond, interfaces.IWidget)
+    zope.component.adapts(
+        zope.interface.Interface, interfaces.IFormLayer,
+        interfaces.IForm, interfaces.IWidget)
+    #zope.component.adapts(zope.interface.Interface, interfaces.IFormLayer,
+    #    interfaces.IForm, zope.schema.interfaces.IObject, interfaces.IWidget)
 
     factory = MySecond
\ No newline at end of file

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/error.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -101,6 +101,23 @@
         return self.error.args[0]
 
 
+class MultipleErrorViewSnippet(ErrorViewSnippet):
+    """Error view snippet for multiple errors."""
+    zope.component.adapts(
+        interfaces.IMultipleErrors, None, None, None, None, None)
+
+    def update(self):
+        output = ''
+        for error in self.error.errors:
+            view = zope.component.getMultiAdapter(
+                (error, self.request, widget, widget.field,
+                 self.form, self.content), interfaces.IErrorViewSnippet)
+            output += view.render()
+        self.output = output
+
+    def render(self):
+        return self.output
+
 class ErrorViewTemplateFactory(object):
     """Error view template factory."""
 

Modified: z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py	2008-10-07 17:37:12 UTC (rev 91877)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/interfaces.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -154,6 +154,10 @@
     def render():
         """Render view."""
 
+class IMultipleErrors(zope.interface.Interface):
+    """An error that contains many errors"""
+    
+    errors = zope.interface.Attribute("List of errors")
 
 # ----[ Fields ]--------------------------------------------------------------
 
@@ -509,7 +513,7 @@
     """Password widget."""
 
 class IObjectWidget(IWidget):
-    """Object widget.""" 
+    """Object widget."""
 
 class IWidgets(IManager):
     """A widget manager"""

Added: z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py
===================================================================
--- z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	                        (rev 0)
+++ z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py	2008-10-07 18:32:12 UTC (rev 91878)
@@ -0,0 +1,146 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Data Converters
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.i18n.format
+import zope.interface
+import zope.component
+import zope.schema
+
+from z3c.form.converter import BaseDataConverter
+
+from z3c.form.dummy import MySubObject
+from z3c.form import form, interfaces
+from z3c.form.field import Fields
+from z3c.form.i18n import MessageFactory as _
+
+class IObjectFactory(zope.interface.Interface):
+    """Factory that will instatiate our objects for ObjectWidget
+    """
+
+    def get(value):
+        """return a default object created to be populated
+        """
+
+class ObjectSubForm(form.BaseForm):
+    zope.interface.implements(interfaces.ISubForm)
+
+    formErrorsMessage = _('There were some errors.')
+    successMessage = _('Data successfully updated.')
+    noChangesMessage = _('No changes were applied.')
+
+    def __init__(self, context, parentWidget):
+        self.context = context
+        self.request = parentWidget.request
+        self.parentWidget = parentWidget
+        self.parentForm = self.__parent__ = parentWidget.form
+
+    def _validate(self):
+        for widget in self.widgets.values():
+            try:
+                # convert widget value to field value
+                converter = interfaces.IDataConverter(widget)
+                value = converter.toFieldValue(widget.value)
+                # validate field value
+                zope.component.getMultiAdapter(
+                    (self.context,
+                     self.request,
+                     self.parentWidget.form,
+                     getattr(widget, 'field', None),
+                     widget),
+                    interfaces.IValidator).validate(value)
+            except (zope.schema.ValidationError, ValueError), error:
+                # on exception, setup the widget error message
+                view = zope.component.getMultiAdapter(
+                    (error, self.request, widget, widget.field,
+                     self.parentWidget.form, self.context),
+                    interfaces.IErrorViewSnippet)
+                view.update()
+                widget.error = view
+
+    def update(self):
+        self.fields = Fields(self.parentWidget.field.schema)
+
+        self.mode = self.parentWidget.mode
+        self.ignoreContext = self.parentWidget.ignoreContext
+        self.ignoreRequest = self.parentWidget.ignoreRequest
+        self.prefix = self.parentWidget.field.__name__
+
+        if interfaces.IFormAware.providedBy(self.parentWidget):
+            self.ignoreReadonly = self.parentWidget.form.ignoreReadonly
+
+        super(ObjectSubForm, self).update()
+
+        self._validate()
+
+
+class ObjectConverter(BaseDataConverter):
+    """Data converter for IObjectWidget."""
+
+    zope.component.adapts(
+        zope.schema.interfaces.IObject, interfaces.IObjectWidget)
+
+    #factory = MySubObject
+    factory = None
+
+    def _fields(self):
+        x = zope.schema.getFields(self.field.schema)
+        return x
+
+    def toWidgetValue(self, value):
+        """Just dispatch it."""
+        if value is self.field.missing_value:
+            return None
+
+        return value
+
+    def createObject(self, value):
+        #keep value passed, maybe some subclasses want it
+
+        if self.factory is None:
+            adapter = zope.component.queryMultiAdapter(
+                (self.widget.context, self.widget.request,
+                 self.widget.form, self.widget),
+                IObjectFactory,
+                name=self.field.schema.__name__)
+            if adapter:
+                obj = adapter.get(value)
+        else:
+            #this is creepy, do we need this?
+            #there seems to be no way to dispatch???
+            obj = self.factory()
+
+        return obj
+
+    def toFieldValue(self, value):
+        """See interfaces.IDataConverter"""
+        if value[1]:
+            #lame, we must be able to show all errors
+            #if len(value[1])>1:
+            #    from pub.dbgpclient import brk; brk('192.168.32.1')
+
+            raise value[1][0].error
+
+        obj = self.createObject(value)
+
+        for name, f in self._fields().items():
+            try:
+                setattr(obj, name, value[0][name])
+            except KeyError:
+                #smells like an input error?
+                pass
+        return obj


Property changes on: z3c.form/branches/adamg-objectwidget/src/z3c/form/object.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native



More information about the Checkins mailing list