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