Home > Mobile >  How to duplicate Django models with OneToOneField relations
How to duplicate Django models with OneToOneField relations

Time:02-17

Start with the following models using django==3.2.12:

from django.db import models


class Root(models.Model):
  pass

class Leaf(models.Model):
  root = models.OneToOneField(Root, related_name='leaf_data', on_delete=models.CASCADE)

Run the following in the shell:

>>> from myapp.models import Root, Leaf
>>> root = Root()
>>> root.save()
>>> leaf = Leaf(root=root)
>>> leaf.save()
>>> root
<Root: Root object (1)>
>>> leaf
<Leaf: Leaf object (1)>
>>> new_root = Root()
>>> new_root.save()
>>> new_root
<Root: Root object (2)>
>>> root.leaf_data
<Leaf: Leaf object (1)>
>>> leaf = root.leaf_data
>>> leaf.pk = None
>>> leaf.root = new_root
>>> leaf.save()
>>> leaf.root
<Root: Root object (2)>
>>> root.leaf_data
<Leaf: Leaf object (2)>

Why does the original root.leaf_data reference change? I would expect that by setting leaf.pk = None and leaf.root = new_root that the original root/leaf structure would remain intact. I'm trying to create a full duplicate from the original.

CodePudding user response:

I didn't change on db. If you do root.refresh_from_db() root.leaf_data should be <Leaf: Leaf object (1)>.

What happened is you used root.leaf_data object to create another Leaf. After save django hydrated this Leaf instance with data of newly created leaf - <Leaf: Leaf object (2)>. But root still points at this object!

If you created new Leaf and not reused the instance the problem wouldn't occur :D

  • Related