一起保存父子模型对象
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
块是你可以知道操作没有进行的地方,它不是你清理延迟对象的地方,你不能这样做,因为事务已经自动回滚了。
以上是关于一起保存父子模型对象的主要内容,如果未能解决你的问题,请参考以下文章