我的问题是保存需要互相引用的新模型,而不仅仅是使用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()
这是正确的方法,还是有另外一种方法可以保存两次?
答案 0 :(得分:4)
无法绕过它,无论如何都需要保存其中一个对象。
这是因为,在数据库级别,您需要保存对象以获取其ID。没有办法告诉sql数据库&#34;保存这两个对象并将id分配给另一个对象上的那些字段&#34;。因此,如果您要手动执行此操作,则可以使用NULL为FK插入第一个对象,返回其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
,它应该可以工作。]
如果由于某种原因(手动编辑,在某处插入错误,......)one.current.owner != one
,您可能希望检查代码在稍后读取数据库时的反应方式。 / p>