在Django管理界面删除对象时,是否有可能禁用相关对象的生成?

4
我目前在维护一个旧系统,同时新系统正在部署。我最近注意到,在尝试删除特定模型中的某些对象时,会出现超时问题。我发现与以下问题有关,该问题已有接受的答案:Django管理页面在尝试编辑/创建时挂起(直至超时错误)
我的问题是,相关的对象与我所问的模型没有直接关系。
例如,我有以下模型(由于我的公司IP原因,名称是通用的):
  • ModelA 是我在 Django 管理页面中删除时遇到问题的模型
  • ModelB 包含对 ModelA 的 ForeignKey 字段
  • ModelC 包含对 ModelB 的 ForeignKey 字段
  • ModelD 包含对 ModelC 的 ForeignKey 字段
  • ModelE 包含对 ModelD 的 ForeignKey 字段
模型详情:
  • ModelE 可以包含任何 entry 中 tens/hundreds/thousands 条数据的条目
  • 对于任何 entry,ModelC 都可以包含 tens/hundreds/thousands 条数据的条目
当前,当我尝试删除 ModelA 时,Django 会尝试生成所有关联对象直到 ModelE,对于具有大量相关的 ModelCModelE 来说,这将导致超时。
是否有一种方法可以避免这种情况,例如通过覆盖自定义模板(如 delete_confirmation_template)或通过其他任何方法?理想情况下,我仍然希望显示摘要,但考虑到这个问题的性质,我不确定是否可能。
一些上下文细节:
  • 我认为这可能是由于我们数据库模式整体结构较差,但正如我之前提到的,这是一个旧系统。
  • 我不需要立即修复此问题,因为除了当前情况/任务(清除重复条目,用户错误未通过正确的表单进行控制;现在表单已检查此问题)外,我永远不会删除此模型的 entry。我只是在清理事项并在测试所述迁移脚本时利用该中间页面作为健全性检查时注意到这一点。
超时截图

哪个版本的Django?各种ForeignKey字段的on_delete值是什么?您是否意味着on_delete设置为CASCADE,因此管理员正在尝试显示所有相关的模型,这些模型也将被删除? - dirkgroten
Django版本1.11,几乎在所有情况下都设置为CASCADE。 - golkedj
首先,我会问自己是否CASCADE是正确的行为(通常在Django版本<2.x中,开发人员只是没有考虑适当的设置,所以默认为CASCADE)。也许你想要它成为SET_NULL,这将解决你的问题。其次,如果CASCADE是正确的行为,那么除了更改超时设置之外,你无能为力:所有相关模型需要被获取的事实不仅仅是由于确认模板的显示,当实际的delete()操作发生时,它也会发生。 - dirkgroten
@dirkgroten 我自己也一直在思考这个问题。考虑到数据的性质和模型,我认为在许多情况下将on_delete设置为SET_NULL更为合适。具体来说,对于ModelC及其后续模型,它们应该永远不会被删除,因为它们是自动化系统的测试结果,应该始终保留。此外,ModelA也可能永远不会被删除。对于我的当前情况,我将简单地禁用管理站点中的删除功能(https://dev59.com/7W855IYBdhLWcg3w_5im)。 - golkedj
您可以在ModelAdmin类上设置has_delete_permission()以返回False(或检查用户的角色,例如仅对于is_superuser返回True),请参见此处 - dirkgroten
@dirkgroten 感谢您的评论。它们非常有帮助。我采用了您建议的“SET_NULL”的修改版本。在我的情况下,虽然“CASCADE”不合适,但“PROTECT”是可以的。 - golkedj
1个回答

1

从评论讨论中,我得出以下结论:

  • 将模型的on_delete设置为CASCADE是错误的,在尝试删除模型时会导致检索相关对象的时间非常长。
  • 由于我不希望在其他特定模型与这些对象有关联时允许删除这些对象,因此我分析并适当地设置了on_deletePROTECT
  • 现在,当我尝试删除一个对象时,由于受保护的相关项,它不会允许我删除该对象。这也解决了我之前观察到的超时问题。

这使我仍然可以通过Django管理站点删除此模型中的对象,如果它们没有相关的受保护对象,这最终是我想要的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接