如何在Django关系中删除一个对象(保持所有相关对象)?

2 投票
2 回答
6775 浏览
提问于 2025-04-16 02:05

我有一个这样的模型:

One
   name (Char)

Many
    one (ForeignKey,blank=True,null=True)
    title (Char)

我想删除一个One实例,并且所有相关的对象都应该失去与这个One实例的关系。目前我的代码是这样的:

one=One.objects.get(<some criterion>)

more=Many.objects.filter(one=one)
for m in more
    m.one=None
    m.save()
#and finally:
one.delete()

这段代码是干什么的呢?它找到要删除的对象,然后搜索与之相关的对象,把它们的外键设置为None,最后删除这个One实例。但是在这个过程中,它还意外地删除了所有相关的对象(Many实例)。我的问题是:为什么这些相关的对象会被删除,我该怎么防止这种情况发生呢?

2 个回答

1

你可以先使用 update() 方法:

Many.objects.filter(one=one).update(one=None)

我觉得 Django 在程序层面上会删除相关的对象(而不是在数据库中使用级联删除)。所以可能你的对象还在某种缓存中,Django 依然认为它们和 one 对象有关联。

在你删除之前,试着先列出相关的对象。

print one.many_set
one.delete()

如果你在这个集合中还有其他对象,可能需要重新从数据库中获取 one 对象,然后再进行删除。或者你可以使用 delete() 方法:

One.objects.filter(<criteria>).delete()
2

给出的代码是正确的。我在提问时遇到的问题是我实现时的一个打字错误。

真是丢人。

不过……还有一些地方可以改进:

more=Many.objects.filter(one=one)
for m in more
    m.one=None
    m.save()
#and finally:
one.delete()

可以写成:

for m in one.many_set.all()
    m.one=None
    m.save()
one.delete()

这和下面的内容是一样的:

one.many_set.clear()
one.delete()

撰写回答