gpt4 book ai didi

django - 有没有办法保存相互引用两次的模型?

转载 作者:行者123 更新时间:2023-12-01 12:34:42 24 4
gpt4 key购买 nike

我的问题是在保存需要相互引用的新模型时,而不仅仅是使用 related_name查找,例如:

class Many:
owner = models.ForeignKey('One')

class One:
current = models.OneToOneField('Many')

默认情况下,这些有 null=False并且,如果我错了,请纠正我,在我改变其中一种关系之前,使用这些是不可能的:

    current = models.OneToOneField('Many', null=True)

原因是您不能将模型分配给关系,除非它已经保存。否则导致 ValueError: 'Cannot assign "<...>": "..." instance isn't saved in the database.' .

但现在当我创建一对这样的对象时,我需要保存两次:

many = Many()
one = One()
one.save()
many.owner = one
many.save()
one.current = many
one.save()

这是正确的方法吗,还是有另一种方法可以节省两次?

最佳答案

没办法,无论如何你都需要将其中一个对象保存两次。

这是因为,在数据库级别,您需要保存一个对象以获取其 ID。没有办法告诉 sql 数据库“保存这 2 个对象并将 id 分配给另一个对象上的那些字段”。因此,如果您要手动执行此操作,您将使用 FK 的 NULL 插入第一个对象,取回其 ID,使用第一个对象的 ID 插入第二个对象,取回其 ID,然后更新要设置的第一个对象FK。您可以将整个事情封装在一个事务中。

因此,您使用 ORM 所做的是最接近的。您可能希望在此基础上添加以下内容:

1) 使用事务进行更改,如下所示:

from django.db import transaction

with transaction.atomic():
many, one = Many(), One()
one.save()
many.owner = one
many.save()
one.current = many
one.save(update_fields=['current']) # slight optimization here

2) 现在这被封装在一个事务中,您可能想要删除 null=True但是你不能,不幸的是,这些是立即检查的。[编辑:看来 Oracle 可能支持推迟 NOT NULL 检查,所以如果您使用的是 Oracle,您可以尝试删除 null=True,它应该可以工作。]

你可能想检查你的代码如何 react ,如果在稍后读取数据库时,如果出于某种原因(手动编辑,某处插入错误,...) one.current.owner ! = 一个

关于django - 有没有办法保存相互引用两次的模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30827132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com