def copy_plugin(self, target_placeholder, target_language, parent_cache, no_signals=False):
    "\n        Copy this plugin and return the new plugin.\n\n        The logic of this method is the following:\n\n         # get a new generic plugin instance\n         # assign the position in the plugin tree\n         # save it to let mptt/treebeard calculate the tree attributes\n         # then get a copy of the current plugin instance\n         # assign to it the id of the generic plugin instance above;\n           this will effectively change the generic plugin created above\n           into a concrete one\n         # copy the tree related attributes from the generic plugin to\n           the concrete one\n         # save the concrete plugin\n         # trigger the copy relations\n         # return the generic plugin instance\n\n        This copy logic is required because we don't know what the fields of\n        the real plugin are. By getting another instance of it at step 4 and\n        then overwriting its ID at step 5, the ORM will copy the custom\n        fields for us.\n        "
    try:
        (plugin_instance, cls) = self.get_plugin_instance()
    except KeyError:
        return
    new_plugin = CMSPlugin()
    new_plugin.placeholder = target_placeholder
    parent_cache[self.pk] = new_plugin
    if self.parent:
        parent = parent_cache[self.parent_id]
        parent = CMSPlugin.objects.get(pk=parent.pk)
        new_plugin.parent_id = parent.pk
        new_plugin.parent = parent
    new_plugin.language = target_language
    new_plugin.plugin_type = self.plugin_type
    if no_signals:
        from cms.signals import pre_save_plugins
        signals.pre_save.disconnect(pre_save_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_save_plugin')
        signals.pre_save.disconnect(pre_save_plugins, sender=CMSPlugin)
        new_plugin._no_reorder = True
    new_plugin.save()
    if plugin_instance:
        plugin_instance = plugin_instance.__class__.objects.get(pk=plugin_instance.pk)
        plugin_instance.pk = new_plugin.pk
        plugin_instance.id = new_plugin.pk
        plugin_instance.placeholder = target_placeholder
        plugin_instance.cmsplugin_ptr = new_plugin
        plugin_instance.language = target_language
        plugin_instance.parent = new_plugin.parent
        plugin_instance.depth = new_plugin.depth
        plugin_instance.path = new_plugin.path
        plugin_instance.numchild = new_plugin.numchild
        plugin_instance._no_reorder = True
        plugin_instance.save()
        old_instance = plugin_instance.__class__.objects.get(pk=self.pk)
        plugin_instance.copy_relations(old_instance)
    if no_signals:
        signals.pre_save.connect(pre_save_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_save_plugin')
    return new_plugin
Copy this plugin and return the new plugin.

The logic of this method is the following:

 # get a new generic plugin instance
 # assign the position in the plugin tree
 # save it to let mptt/treebeard calculate the tree attributes
 # then get a copy of the current plugin instance
 # assign to it the id of the generic plugin instance above;
   this will effectively change the generic plugin created above
   into a concrete one
 # copy the tree related attributes from the generic plugin to
   the concrete one
 # save the concrete plugin
 # trigger the copy relations
 # return the generic plugin instance

This copy logic is required because we don't know what the fields of
the real plugin are. By getting another instance of it at step 4 and
then overwriting its ID at step 5, the ORM will copy the custom
fields for us.
def copy_plugin(self, target_placeholder, target_language, parent_cache, no_signals=False):
    "\n        Copy this plugin and return the new plugin.\n\n        The logic of this method is the following:\n\n         # get a new generic plugin instance\n         # assign the position in the plugin tree\n         # save it to let mptt/treebeard calculate the tree attributes\n         # then get a copy of the current plugin instance\n         # assign to it the id of the generic plugin instance above;\n           this will effectively change the generic plugin created above\n           into a concrete one\n         # copy the tree related attributes from the generic plugin to\n           the concrete one\n         # save the concrete plugin\n         # trigger the copy relations\n         # return the generic plugin instance\n\n        This copy logic is required because we don't know what the fields of\n        the real plugin are. By getting another instance of it at step 4 and\n        then overwriting its ID at step 5, the ORM will copy the custom\n        fields for us.\n        "
    try:
        (plugin_instance, cls) = self.get_plugin_instance()
    except KeyError:
        return
    new_plugin = CMSPlugin()
    new_plugin.placeholder = target_placeholder
    parent_cache[self.pk] = new_plugin
    if self.parent:
        parent = parent_cache[self.parent_id]
        parent = CMSPlugin.objects.get(pk=parent.pk)
        new_plugin.parent_id = parent.pk
        new_plugin.parent = parent
    new_plugin.language = target_language
    new_plugin.plugin_type = self.plugin_type
    if no_signals:
        from cms.signals import pre_save_plugins
        signals.pre_save.disconnect(pre_save_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_save_plugin')
        signals.pre_save.disconnect(pre_save_plugins, sender=CMSPlugin)
        new_plugin._no_reorder = True
    new_plugin.save()
    if plugin_instance:
        plugin_instance = plugin_instance.__class__.objects.get(pk=plugin_instance.pk)
        plugin_instance.pk = new_plugin.pk
        plugin_instance.id = new_plugin.pk
        plugin_instance.placeholder = target_placeholder
        plugin_instance.cmsplugin_ptr = new_plugin
        plugin_instance.language = target_language
        plugin_instance.parent = new_plugin.parent
        plugin_instance.depth = new_plugin.depth
        plugin_instance.path = new_plugin.path
        plugin_instance.numchild = new_plugin.numchild
        plugin_instance._no_reorder = True
        plugin_instance.save()
        old_instance = plugin_instance.__class__.objects.get(pk=self.pk)
        plugin_instance.copy_relations(old_instance)
    if no_signals:
        signals.pre_save.connect(pre_save_plugins, sender=CMSPlugin, dispatch_uid='cms_pre_save_plugin')
    return new_plugin