Created
March 1, 2023 21:26
-
-
Save gfranxman/97c457a0e52d01a7e5117db02e72188d to your computer and use it in GitHub Desktop.
Cloning Django objects pattern
This file contains hidden or 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 model_to_dict(instance, exclude: list = None, modify: dict = None): | |
excluded_fields = ["id", "pk"] | |
if exclude: | |
excluded_fields.extend(exclude) | |
defaults = dict( | |
[ | |
(fld.name, getattr(instance, fld.name)) | |
for fld in instance._meta.fields | |
if fld.name not in excluded_fields | |
] | |
) | |
if modify: | |
for k, v in modify: | |
if v: | |
defaults[k] = v | |
else: | |
del defaults[k] | |
return defaults | |
def clone_mymodel(instance): | |
fk1_clone = clone_fk1(instance.fk1) | |
fk2_clone = clone_fk2(instance.fk2) | |
m2m1_clones = [] | |
for m2m in instance.m2m1.all(): | |
m2m1_clones.append( clone_m2m1 ) | |
defaults = model_to_dict(instance, exclude=["name", "fk1", "fk2", "m2m1"]) | |
clone, is_new = MyModel.objects.get_or_create(name=f"{instance.name}-clone", defaults=defaults ) | |
clone.fk1 = fk1_clone | |
clone.fk2 = fk2_clone | |
clone.save() | |
for m2m1_clone in m2m1_clones: | |
clone.m2m1.add(m2m1_clone) | |
return clone |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment