joz*_*yqk 4 django django-models
我的问题是在保存需要相互引用的新模型时,而不仅仅是使用查找related_name,如下所示:
class Many:
owner = models.ForeignKey('One')
class One:
current = models.OneToOneField('Many')
Run Code Online (Sandbox Code Playgroud)
默认情况下,这些具有null=False并且,如果我错了,请纠正我,除非我更改其中一种关系,否则不可能使用这些:
current = models.OneToOneField('Many', null=True)
Run Code Online (Sandbox Code Playgroud)
原因是因为除非模型已保存,否则您无法将模型分配给关系。否则导致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()
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗,还是有其他方法可以节省两次?
没有办法解决这个问题,无论如何你都需要保存其中一个对象两次。
\n\n这是因为,在数据库级别,您需要保存对象才能获取其 ID。没有办法告诉 sql 数据库“保存这两个对象并将 id 分配给另一个对象上的这些字段”。因此,如果您要手动执行此操作,您将 INSERT 第一个对象的 FK 为 NULL,获取其 ID,INSERT 第二个对象的第一个对象的 ID,获取其 ID,然后更新要设置的第一个对象FK。\n您可以将整个事情封装在一个事务中。
\n\n因此,您使用 ORM 所做的事情是您能得到的最接近的结果。您可能需要添加以下内容:
\n\n1)使用事务进行更改,如下所示:
\n\nfrom django.db import transaction\n\nwith transaction.atomic():\n many, one = Many(), One()\n one.save()\n many.owner = one\n many.save()\n one.current = many\n one.save(update_fields=[\'current\']) #\xc2\xa0slight optimization here\nRun Code Online (Sandbox Code Playgroud)\n\n2) 现在这被封装在一个事务中,您可能想要删除null=True. 但不幸的是,您不能立即检查这些内容。\n[编辑:Oracle 可能支持推迟 NOT NULL 检查,因此,如果您正在使用 Oracle,您可以尝试删除null=True它应该可以工作。]
您可能想要检查代码在稍后读取数据库时的反应,如果出于某种原因(手动编辑、有缺陷的插入某处,...)one.current.owner != one。
| 归档时间: |
|
| 查看次数: |
1802 次 |
| 最近记录: |