Skip to content

Instantly share code, notes, and snippets.

@zopyx
Created September 19, 2014 08:04
Show Gist options
  • Save zopyx/2fb8fc905db542807fe1 to your computer and use it in GitHub Desktop.
Save zopyx/2fb8fc905db542807fe1 to your computer and use it in GitHub Desktop.
CORRECT copying of all fields from one Dexterity content object to another instance of the same type
def clone_plone_metadata(source, target):
""" Copy all metadata key-value pairs of the 'source'
Dexterity content-object to 'target'.
"""
from plone.dexterity.interfaces import IDexterityFTI
from plone.behavior.interfaces import IBehaviorAssignable
if not isinstance(source, target.__class__):
raise TypeError('source and target must be the same class ({} vs {})'.format(source.__class__, target.__class__))
schema = getUtility(IDexterityFTI, name=source.portal_type).lookupSchema()
fields = [(schema, schema[name]) for name in schema]
assignable = IBehaviorAssignable(source)
for behavior in assignable.enumerateBehaviors():
behavior_schema = behavior.interface
for name in behavior_schema:
fields.append((behavior_schema, behavior_schema[name]))
for schema_adapter, field in fields:
source_adapted = schema_adapter(source)
target_adapted = schema_adapter(target)
value = getattr(source_adapted, field.getName())
if isinstance(value, str):
value = unicode(value, 'utf-8')
setattr(target_adapted, field.getName(), value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment