一起保存父子模型对象

Posted

技术标签:

【中文标题】一起保存父子模型对象【英文标题】:Save parent and child model object together 【发布时间】:2018-06-06 12:32:46 【问题描述】:

我使用 Django 2.0 和 mysql 数据库,我的项目模型是这样的:

class Parent(models.Model):
    name = models.CharField()

class Child(models.Model):
    number = models.IntegerField()
    parent = models.ForeignKey(Parent)

我想要的是同时保存父对象和子对象,以便在任何情况下子对象有错误(如数字字段是“某些文本”)并且无法保存父对象不保存。

在 Flask(使用 postgresql)中有 add(object) 和 add_all([parent, child]) 方法,我使用 add_all 所以如果 child 有错误 parent 也不会保存。

但是在 Django 中我找不到这个方法。

默认方法是:

parent = Parent(name = "my name")
parent.save()

child = Child(number=3, parent=parent)
child.save()

我想要的是这样的:

parent = Parent(name = "my name")
child = Child(number=3, parent=parent)

然后:

child.save(with related parent)

或:

save(parent, child together)

PS:我阅读了这个链接,我认为“SET”方法是我需要的,但我不确定如何使用它以及是否是解决方案: django relations

【问题讨论】:

您对 Django 的 RelatedManager 类有什么不清楚的地方?告诉我们“我想不通”对我们没有帮助。 问题已编辑 【参考方案1】:

我想要的是同时保存父对象和子对象,这样如果在任何情况下子对象有错误 [...] 并且无法保存,父对象也不会保存。

在我看来,您可以为此使用 database transaction。在事务中,要么所有操作都通过,要么全部回滚,没有半途而废(在您的情况下,如果没有保存父级,则不会保存子级)

下面是一个使用transaction.atomic的例子:

from django.db import DatabaseError, transaction
try:
    with transaction.atomic():
        parent = Parent(name = "my name")
        parent.save()

        child = Child(number=3, parent=parent)
        child.save()

except DatabaseError:
    # Handle the case where an error prevented the operation

【讨论】:

我不能使用这种方法,因为我有多达 4 层相关对象,并且在您的代码中,父对象将在数据库中创建,我必须在 except 中删除它。我想要的是禁止在数据库中保存父级。 顺便提一下,你提到了 Flask 和 PostgreSQL。如果您将 SQLAlchemy 与 Flask 一起使用,那么请知道它默认在事务中运行并且不会自动提交,并且您必须运行例如db.session.commit() 既提交子节点又提交父节点或两者都不提交。 是的。确切地。我希望 django 中的同一件事同时将父母和孩子一起提交。两者都或都不是。还是谢谢。 “父对象将在数据库中创建,我必须在 except 中删除它”,不,那是在事务中运行的重点,它是原子的,一切顺利或无事可做。如果您有两个以上的关系(实际上并不重要),请将所有操作放在一个事务中,这将保证它以原子方式运行。同样,这就是数据库有事务的原因。 简单地说:transaction.atomic 中的所有操作要么执行,要么不执行。 except 块是你可以知道操作没有进行的地方,它不是你清理延迟对象的地方,你不能这样做,因为事务已经自动回滚了。

以上是关于一起保存父子模型对象的主要内容,如果未能解决你的问题,请参考以下文章

在插入新的子对象时,父子对象传递与多级的一对多关系。 IOS核心数据

QT之对象父子关系

QT窗口组件的父子关系

7.QT-Qt对象间的父子关系

如何从 Vapor 3 中的 JSON 响应中保存父子关系

非父子组件间通信