如何检查 Django 中将级联删除的对象?

Posted

技术标签:

【中文标题】如何检查 Django 中将级联删除的对象?【英文标题】:How can I check what objects will be cascade deleted in Django? 【发布时间】:2014-11-07 18:36:42 【问题描述】:

在 Django 的 /admin/ 部分,您可以选择删除项目。

如果任何相关对象将与您选择的对象一起被删除,您会在确认删除之前看到受影响对象的列表。

我可以在我自己的函数中以编程方式检查吗?

我想做类似的事情

for item in Item.objects.all():
    if not deletion_would_also_delete_other_objects(item):
        item.delete()

【问题讨论】:

How to show related items using DeleteView in Django?的可能重复 【参考方案1】:

您可以使用 from django.db.models.deletion import Collector 来执行此操作吗?

from django.db.models.deletion import Collector
from .models import Item
  
for item in Item.objects.all(): 
    collector = Collector(using='default')
    collector.collect([item])

    # dependencies should be an empty dict if the item is not related to anything
    if not collector.dependencies:
        item.delete()

【讨论】:

我在 Django 1.9 中的 collector.collect([item]) 上得到了 TypeError: hasattr(): attribute name must be string。如果我在实例化收集器时指定 using 参数,则此问题已修复:collector = Collector(using='default') 我不确定这是否准确(至少现在如此)。我发现.dependencies 是空的,但是.data.fast_deletes 都显示了很多将被删除的对象。 确实,前 2 个 cmets 的两条信息都应该包含在答案中。 根据代码中的cmets [github.com/django/django/blob/master/django/db/models/…,.fast_deletes只包含不级联的东西,看起来.data只包含了收集到的对象本身的值。所以我认为更新后的帖子是正确的。【参考方案2】:

我建议使用 django admin 中提供的NestedObjects util。

from django.contrib.admin.utils import NestedObjects
from django.db import router

using = router.db_for_write(Item._meta.model)
# if you only have one database, just set using = "default"

nested_object = NestedObjects(using)
nested_object.collect([Item])
# If you want to delete multi item, you can use:
# nested_object.collect(Model.objects.filter(type="deleted"))

print(nested_object.nested()

结果如下所示:

【讨论】:

以上是关于如何检查 Django 中将级联删除的对象?的主要内容,如果未能解决你的问题,请参考以下文章

SQL 级联更新,级联删除的概念

如何阻止这种级联删除在 Django 中发生?

Django级联删除反向外键

如何使用不会将删除级联到其子级的 ForeignKeys 创建 Django 模型?

Django,级联移动到单独的表而不是级联删除

为啥 Django 对外键进行级联删除?