Как дублировать модели Django с помощью отношений OneToOneField

Начните со следующих моделей, используя 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)

Запустите в командной оболочке следующее:

>>> 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)>

Почему изменяется исходная ссылка root.leaf_data? Я бы ожидал, что при установке leaf.pk = None и leaf.root = new_root исходная структура корень/лист останется нетронутой. Я пытаюсь создать полный дубликат из оригинала.

Я не менял на db. Если вы сделаете root.refresh_from_db() root.leaf_data должно быть <Leaf: Leaf object (1)>.

Что произошло: вы использовали объект root.leaf_data для создания другого листа. После save django гидратировал этот Leaf экземпляр с данными вновь созданного листа - <Leaf: Leaf object (2)>. Но root по-прежнему указывает на этот объект!

Если бы вы создали новый Leaf и не использовали повторно экземпляр, проблема бы не возникла :D

Вернуться на верх