# Imports
from django.core import serializers
from json import dumps as json_dumps, loads as json_loads
from superdjango.exceptions import DeeplyDisturbingError
from superdjango.shortcuts import get_model
# Functions
[docs]def dump_polymorphic_data(model_name):
"""Dump JSON data for the given model.
:param model_name: The model to export in app_name.ModelName format.
:type model_name: str
:rtype: str
:raise: DeeplyDisturbingError
"""
# Load the model class.
model = get_model(model_name, raise_exception=False)
if model is None:
raise DeeplyDisturbingError("Model does not exist: %s" % model_name)
# Get the field instance of the o2o pointer.
try:
pointer_field = model.get_pointer_field()
except AttributeError:
raise DeeplyDisturbingError("%s.get_pointer_field() is not defined." % model.__name__)
# Assemble rows for serialization. Parent instances are captured for serialization below.
parents = dict()
rows = list()
qs = model.objects.all()
for row in qs:
parent = getattr(row, pointer_field.name)
parents[row.pk] = parent
rows.append(row)
# Serialize the child data. There doesn't seem to be a better way to do this than serialize to JSON and immediately
# convert to a Python object so that the ptr ID can be added.
children = json_loads(serializers.serialize("json", [*rows]))
for child in children:
record_id = child['pk']
child['fields'][pointer_field.name + "_id"] = parents[record_id].pk
# Assemble parent instances into a list that may be serialized.
_parents = list()
for record_id, parent in parents.items():
_parents.append(parent)
# Serialize parents and immediately reload as a Python object.
data = json_loads(serializers.serialize("json", [*_parents]))
# Add children.
data += children
# Return the combined data as JSON.
return json_dumps(data, indent=4)