diff --git a/docs/HISTORY.txt b/docs/HISTORY.txt index 54a7d3d..c51b411 100644 --- a/docs/HISTORY.txt +++ b/docs/HISTORY.txt @@ -4,6 +4,10 @@ Changelog 2.0.1 (unreleased) ------------------ +- The default attribute accessor now also looks through subtypes + (behaviors) to find a field default. + [malthe] + - Added support in the FTI to look up behaviors by utility name when getting additional schemata (i.e. fields provided by behaviors). diff --git a/plone/dexterity/content.py b/plone/dexterity/content.py index bf8d39b..2c6912b 100644 --- a/plone/dexterity/content.py +++ b/plone/dexterity/content.py @@ -185,7 +185,13 @@ class DexterityContent(DAVResourceMixin, PortalContent, DefaultDublinCoreImpl, C field = schema.get(name, None) if field is not None: return deepcopy(field.default) - + + # do the same for each subtype + for schema in SCHEMA_CACHE.subtypes(self.portal_type): + field = schema.get(name, None) + if field is not None: + return deepcopy(field.default) + raise AttributeError(name) # Let __name__ and id be identical. Note that id must be ASCII in Zope 2, diff --git a/plone/dexterity/tests/test_content.py b/plone/dexterity/tests/test_content.py index 38b2368..ff9fdd7 100644 --- a/plone/dexterity/tests/test_content.py +++ b/plone/dexterity/tests/test_content.py @@ -231,7 +231,7 @@ class TestContent(MockTestCase): pass class ISubtype(Interface): - pass + baz = zope.schema.TextLine(title=u"baz", default=u"baz") behavior1 = BehaviorRegistration(u"Behavior1", "", IBehavior1, None, None) behavior2 = BehaviorRegistration(u"Behavior2", "", IBehavior2, ISubtype, None) @@ -258,7 +258,10 @@ class TestContent(MockTestCase): # the cache. This is not the case, as evidenced by .count(1) above. self.assertEquals(True, ISubtype.providedBy(item)) self.assertEquals(True, ISchema.providedBy(item)) - + + # Subtypes provide field defaults. + self.assertEquals(u"baz", getattr(item, "baz", None)) + # We also need to ensure that the _v_ attribute doesn't hide any # interface set directly on the instance with alsoProvides() or # directlyProvides(). This is done by clearing the cache when these