[Checkins] SVN: zope.app.form/trunk/ Added changelog and refactored
applyChanges() to set up the location for newly
Christian Theune
ct at gocept.com
Sat Jul 7 05:48:12 EDT 2007
Log message for revision 77562:
Added changelog and refactored applyChanges() to set up the location for newly
created objects.
Changed:
A zope.app.form/trunk/CHANGES.txt
U zope.app.form/trunk/src/zope/app/form/browser/objectwidget.py
U zope.app.form/trunk/src/zope/app/form/browser/objectwidget.txt
U zope.app.form/trunk/src/zope/app/form/browser/tests/test_objectwidget.py
-=-
Added: zope.app.form/trunk/CHANGES.txt
===================================================================
--- zope.app.form/trunk/CHANGES.txt (rev 0)
+++ zope.app.form/trunk/CHANGES.txt 2007-07-07 09:48:11 UTC (rev 77562)
@@ -0,0 +1,17 @@
+=======
+Changes
+=======
+
+After 3.4.0b1
+=============
+
+ - Made the object widget set up location for objects that are instanciated by
+ the object widget itself. (#98287)
+
+
+Before 3.4
+==========
+
+This package was part of the Zope 3 distribution and did not have its own
+CHANGES.txt. For earlier changes please refer to either our subversion log or
+the CHANGES.txt of earlier Zope 3 releases.
Property changes on: zope.app.form/trunk/CHANGES.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.app.form/trunk/src/zope/app/form/browser/objectwidget.py
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/objectwidget.py 2007-07-07 09:47:47 UTC (rev 77561)
+++ zope.app.form/trunk/src/zope/app/form/browser/objectwidget.py 2007-07-07 09:48:11 UTC (rev 77562)
@@ -17,6 +17,8 @@
"""
__docformat__ = 'restructuredtext'
+import zope.location.interfaces
+import zope.location.location
from zope import component
from zope.interface import implements
from zope.schema import getFieldNamesInOrder
@@ -148,27 +150,29 @@
return content
-
def applyChanges(self, content):
field = self.context
-
- # create our new object value
- value = field.query(content, None)
- if value is None:
+ obj = field.query(content, None)
+ if obj is None:
+ # The object doesn't exist yet, so we create a new one. Existing
+ # objects are updated, not re-created.
+ obj = self.factory()
# TODO: ObjectCreatedEvent here would be nice
- value = self.factory()
- # apply sub changes, see if there *are* any changes
- # TODO: ObjectModifiedEvent here would be nice
- changes = applyWidgetsChanges(self, field.schema, target=value,
+ # Locate the new object
+ if not zope.location.interfaces.ILocation.providedBy(obj):
+ obj = zope.location.location.LocationProxy(obj)
+ obj.__parent__ = content
+ obj.__name__ = field.__name__
+
+ # Apply the actual changes to the object.
+ changes = applyWidgetsChanges(self, field.schema, target=obj,
names=self.names)
-
- # if there's changes, then store the new value on the content
if changes:
- field.set(content, value)
- # TODO: If value implements ILocation, set name to field name and
- # parent to content
-
+ # Store the object on the content. We do this both in the case of
+ # newly created as well as updated objects because field.set runs
+ # some more validation on the schema-conformance.
+ field.set(content, obj)
return changes
def hasInput(self):
Modified: zope.app.form/trunk/src/zope/app/form/browser/objectwidget.txt
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/objectwidget.txt 2007-07-07 09:47:47 UTC (rev 77561)
+++ zope.app.form/trunk/src/zope/app/form/browser/objectwidget.txt 2007-07-07 09:48:11 UTC (rev 77562)
@@ -74,7 +74,7 @@
>>> IPerson.providedBy(family.father)
True
-Let's define a dummy class which doesn't implements IPerson:
+Let's define a dummy class which doesn't implement IPerson:
>>> class Dummy(object):
... """Dummy class."""
@@ -147,3 +147,62 @@
So, now you know my mothers and fathers name. I hope it's also clear how to
use the Object field and the ObjectWidget.
+
+
+Locating objects from the object field
+======================================
+
+Objects that are created through the object field are located automatically.
+If they do not implement the ILocation interface, they will be wrapped with a
+location proxy. We need to do this to make location-based security work
+correctly.
+
+Read carefully (again): Only when the objects are created through the object
+field, they will be located by the object field. If you create the objects
+yourself, you're responsible for setting up any location that is required.
+
+Let's start with a new family. The existing Person class doesn't implement
+ILocation, but it still receives a parent and a name. This is done by using a
+location proxy:
+
+ >>> family = Family()
+ >>> widget.applyChanges(family)
+ True
+ >>> from zope.location.interfaces import ILocation
+ >>> ILocation.implementedBy(family.mother.__class__)
+ False
+ >>> family.mother.__parent__
+ <Family object at 0x...>
+ >>> family.mother.__name__
+ 'mother'
+ >>> type(family.mother)
+ <class 'zope.location.location.LocationProxy'>
+
+To demonstrate this with a class that implements ILocation, we derive Person
+to a LocatedPerson, and we start with a fresh family to force the widget to
+re-create the object:
+
+ >>> from zope.location.location import Location
+ >>> class LocatedPerson(Location, Person):
+ ... pass
+ >>> family = Family()
+
+We create a widget that uses this class as the factory, apply the request
+again, and see that this time, the object is not wrapped by a location proxy:
+
+ >>> factory = LocatedPerson
+ >>> request.form['field.mother.name'] = u'Isabel Ineichen'
+ >>> widget = ObjectWidget(mother_field, request, factory)
+ >>> widget.applyChanges(family)
+ True
+
+ >>> ILocation.implementedBy(family.mother.__class__)
+ True
+ >>> family.mother.__parent__
+ <Family object at 0x...>
+ >>> family.mother.__name__
+ 'mother'
+ >>> family.mother
+ <LocatedPerson object at 0x...>
+ >>> type(family.mother)
+ <class 'LocatedPerson'>
Modified: zope.app.form/trunk/src/zope/app/form/browser/tests/test_objectwidget.py
===================================================================
--- zope.app.form/trunk/src/zope/app/form/browser/tests/test_objectwidget.py 2007-07-07 09:47:47 UTC (rev 77561)
+++ zope.app.form/trunk/src/zope/app/form/browser/tests/test_objectwidget.py 2007-07-07 09:48:11 UTC (rev 77562)
@@ -126,7 +126,8 @@
unittest.makeSuite(ObjectWidgetTest),
doctest.DocFileSuite('../objectwidget.txt',
setUp=setup.placelessSetUp,
- tearDown=setup.placelessTearDown),
+ tearDown=setup.placelessTearDown,
+ optionflags=doctest.ELLIPSIS),
doctest.DocTestSuite(),
))
More information about the Checkins
mailing list