Skip to content

Commit

Permalink
Added customization of export/import data via user defined functions (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
wfehr committed Jul 27, 2023
1 parent 66051dc commit 7a1a005
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
46 changes: 46 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,52 @@ For a manual install:
* run ``python manage.py migrate djangocms_transfer``


Customization
-------------

Following settings are available:

* **DJANGOCMS_TRANSFER_PROCESS_EXPORT_PLUGIN_DATA**:

Enables processing of plugin instances prior to serialization, e.g.
``myapp.module.function``.

* **DJANGOCMS_TRANSFER_PROCESS_IMPORT_PLUGIN_DATA**:

Enables processing of plugin instances prior to saving, e.g.
``myapp.module.function``.
For example: set default-values for ForeignKeys (images for django_filer, ..)

As an example the combination of ``_PROCESS_EXPORT_PLUGIN_DATA`` and
``_PROCESS_IMPORT_PLUGIN_DATA`` lets you export and import the data between
different systems while setting the contents as you need it::

# settings.py
.._PROCESS_EXPORT_PLUGIN_DATA = "myapp.some.module.export_function"
.._PROCESS_IMPORT_PLUGIN_DATA = "myapp.some.module.import_function"

# custom functions
def export_function(plugin, plugin_data):
# remove child-plugins which can't be handled
if plugin.parent_id and plugin.parent.plugin_type == "SomeParentPlugin":
return None
# change data
if plugin.plugin_type == "SomePlugin":
plugin_data["data"].update({
"some_field": "TODO: change me",
})
return plugin_data

def import_function(deserialized_object):
some_related_object = MyModel.objects.first()
for field in deserialized_object.object._meta.fields:
# example of setting a default value for a related field
if isinstance(field, ForeignKey):
value = getattr(deserialized_object.object, field.attname)
if field.related_model == MyModel and value is not None:
setattr(deserialized_object.object, field.name, some_related_object)


Running Tests
-------------

Expand Down
8 changes: 8 additions & 0 deletions djangocms_transfer/datastructures.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections import namedtuple

Check failure on line 1 in djangocms_transfer/datastructures.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.

from django.core.serializers import deserialize
from django.conf import settings
from django.db import transaction
from django.utils.encoding import force_str
from django.utils.functional import cached_property
Expand Down Expand Up @@ -55,6 +56,13 @@ def restore(self, placeholder, language, parent=None, with_data=True):
_d_instance.object._no_reorder = True
_d_instance.object.cmsplugin_ptr = plugin
plugin.set_base_attr(_d_instance.object)

# customize plugin-data on import with configured function
pps = getattr(settings, "DJANGOCMS_TRANSFER_PROCESS_IMPORT_PLUGIN_DATA", None)
if pps:
module, function = pps.rsplit(".", 1)
getattr(__import__(module, fromlist=[""]), function)(_d_instance)

_d_instance.save()
return _d_instance.object
return plugin
9 changes: 8 additions & 1 deletion djangocms_transfer/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections import defaultdict

Check failure on line 1 in djangocms_transfer/helpers.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.

from django.core import serializers
from django.conf import settings

from . import get_serializer_name
from .utils import get_plugin_fields, get_plugin_model
Expand Down Expand Up @@ -53,4 +54,10 @@ def get_plugin_data(plugin, only_meta=False):
'parent_id': plugin.parent_id,
'data': custom_data,
}
return plugin_data

gpd = getattr(settings, "DJANGOCMS_TRANSFER_PROCESS_EXPORT_PLUGIN_DATA", None)
if gpd:
module, function = gpd.rsplit(".", 1)
return getattr(__import__(module, fromlist=[""]), function)(plugin, plugin_data)
else:
return plugin_data
5 changes: 5 additions & 0 deletions djangocms_transfer/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ def import_plugins(plugins, placeholder, language, root_plugin_id=None):
tree_order = placeholder.get_plugin_tree_order(language, parent_id=root_plugin_id)

for archived_plugin in plugins:
# custom handling via "get_plugin_data" can lead to "null"-values
# instead of plugin-dictionaries. We skip those here.
if archived_plugin is None:
continue

if archived_plugin.parent_id:
parent = source_map[archived_plugin.parent_id]
else:
Expand Down

0 comments on commit 7a1a005

Please sign in to comment.