【问题标题】:Django List objects that will be deleted by deleting the current objectDjango列出将通过删除当前对象删除的对象
【发布时间】:2020-01-31 20:57:57
【问题描述】:

在我的 DeleteView 模板中,我想警告用户删除当前对象将删除以下对象(因为 db 架构需要 on_delete = models.CASCADE)。

这是一个示例模型:

class Book(models.Model):
    course = models.ForeignKey(Course, related_name = 'course_books', on_delete = models.CASCADE, null = True, blank = True)

class Exercise(models.Model):
    book = models.ForeignKey(Book, related_name = 'exercises', on_delete = models.CASCADE, null = True, blank = True)
    ...

class Solution(models.Model):
    exercise = models.ForeignKey(Exercise, related_name = 'solutions', on_delete = models.CASCADE, null = True, blank = True)

因此,假设用户想要删除一门课程,我想警告用户在删除当前书籍时将删除哪些书籍、练习和解决方案。大意是这样的:

WARNING: Deleting course Programming 101 will delete Python Programming for Beginners and Python By Example.  It will also delete Excersises 1-5 and solutions 1-10

这将要求我可以查看相关字段以查看 on_delete 是否设置为 CASCADE。如果是,我应该将它添加到 to_be_deleted 对象列表中。

我已经查看了是否可以检查该字段的 on_delete 属性:

for related_object in the_course._meta.related_objects:
    dir(related_object.field)

但没有任何帮助,所以我在这里伸出援手......

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    你可以这样做

    from django.contrib.admin.utils import NestedObjects
    from django.db import DEFAULT_DB_ALIAS
    
    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([obj])
    print(collector.nested())
    

    【讨论】:

    • 我不得不转移到项目的另一部分。我正在重新访问 DeleteView 并运行您的代码。当我输入the_project = Project.objects.filter(name__icontains = 'some_name') 我得到AttributeError: 'QuerySet' object has no attribute '_meta' 我确实运行了help(collector.collect),它确实说我必须将QuerySet 传递给它,但我仍然得到错误
    【解决方案2】:

    您可以使用特定的object_id 过滤对象。例如:

    qs = Solution.objects.filter(exercise__book__course_id=course_id).select_related('exercise__book')
    

    这将给出解决方案的所有对象以及相关外键对象exercisebook 的查询集。然后,您可以遍历此查询集并检查 instance._meta.app_label 以区分对象。

    【讨论】:

    • 此解决方案有效,但它是一种解决方案,因为您必须了解相关对象并手动完成所有工作。在关系跨多个应用程序的网站上,这是不切实际的。因此,您的解决方案非常感谢和帮助,但我现在会等待另一个解决方案
    • 好的,那么你应该编辑你的问题,让它再次处于活动状态,否则它不会得到足够的关注。
    猜你喜欢
    • 2013-10-23
    • 2019-01-05
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    • 2023-03-24
    • 2016-03-20
    相关资源
    最近更新 更多