Created
August 15, 2019 19:37
-
-
Save aj07mm/4c8120b530ef26da807fad3acbb998ca to your computer and use it in GitHub Desktop.
derive.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def derive(obj): | |
from django.contrib.admin.utils import NestedObjects | |
from django.db import DEFAULT_DB_ALIAS | |
from django.db.models.fields.related import ForeignKey | |
""" | |
Derive a new model instance from previous one, | |
and point all related fields to the new instance | |
""" | |
obj2 = copy.copy(obj) | |
obj2.pk = None | |
obj2.save() | |
collector = NestedObjects(using=DEFAULT_DB_ALIAS) | |
collector.collect([obj]) | |
collector.sort() | |
related_models = collector.data.keys() | |
data_snapshot = {} | |
for key in collector.data.keys(): | |
data_snapshot.update({ | |
key: dict( | |
zip( | |
[item.pk for item in collector.data[key]], | |
[item for item in collector.data[key]] | |
) | |
) | |
}) | |
duplicate_order = reversed(related_models) | |
for model in duplicate_order: | |
# Find all FKs on model that point to a related_model. | |
fks = [] | |
for f in model._meta.fields: | |
if isinstance(f, ForeignKey) and f.rel.to in related_models: | |
fks.append(f) | |
# Replace each `sub_obj` with a duplicate. | |
if model not in collector.data: | |
continue | |
sub_objects = collector.data[model] | |
for obj in sub_objects: | |
for fk in fks: | |
dupe_obj = copy.copy(obj) | |
setattr(dupe_obj, fk.name, obj2) | |
dupe_obj.pk = None | |
dupe_obj.save() | |
return obj2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment