什么是覆盖Django的级联删除行为的选项? [英] What are the options for overriding Django's cascading delete behaviour?

查看:180
本文介绍了什么是覆盖Django的级联删除行为的选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Django模型通常会非常适合处理ON DELETE CASCADE行为(以某种方式适用于不支持本机的数据库)。



但是,在以下情况下,我们努力发现什么是覆盖此行为的最佳方法,例如:




  • ON DELETE RESTRICT(即防止删除对象,如果它有子记录)


  • ON DELETE SET NULL(即不删除子记录,但设置


  • 删除记录时更新其他相关数据(例如,删除上传的图像文件)




以下是我了解到以下几种方法:




  • 覆盖模型的 delete()方法。虽然这样的作品,当通过 QuerySet 删除记录时,它是回避的。此外,每个模型的 delete()必须被覆盖,以确保Django的代码从不被调用,并且 super() can'被调用,因为它可以使用 QuerySet 来删除子对象。


  • 使用信号。这似乎是理想的,因为直接删除模型或通过QuerySet删除时调用它们。但是,不可能防止子对象被删除,因此不能实现ON CASCADE RESTRICT或SET NULL。


  • 使用数据库引擎(Django在这种情况下做什么?)


  • 等到Django支持它(直到那时才生成bug) p>




似乎第一个选项是唯一可行的选择,但它是丑陋的,用洗澡水抛出宝宝,并且当添加新的模型/关系时,有可能丢失某些东西。



我错过了什么?任何建议?

解决方案

只是一个注意到那些遇到这个问题的人,现在有一个内置的解决方案Django 1.3。



请参阅文档 django.db.models.ForeignKey.on_delete 感谢Code片段的编辑指出。



最简单的可能场景只是添加您的模型FK字段定义:

  on_delete = models.SET_NULL 


Django models generally handle the ON DELETE CASCADE behaviour quite adequately (in a way that works on databases that don't support it natively.)

However, I'm struggling to discover what is the best way to override this behaviour where it is not appropriate, in the following scenarios for example:

  • ON DELETE RESTRICT (i.e. prevent deleting an object if it has child records)

  • ON DELETE SET NULL (i.e. don't delete a child record, but set it's parent key to NULL instead to break the relationship)

  • Update other related data when a record is deleted (e.g. deleting an uploaded image file)

The following are the potential ways to achieve these that I am aware of:

  • Override the model's delete() method. While this sort of works, it is sidestepped when the records are deleted via a QuerySet. Also, every model's delete() must be overridden to make sure Django's code is never called and super() can't be called as it may use a QuerySet to delete child objects.

  • Use signals. This seems to be ideal as they are called when directly deleting the model or deleting via a QuerySet. However, there is no possibility to prevent a child object from being deleted so it is not usable to implement ON CASCADE RESTRICT or SET NULL.

  • Use a database engine that handles this properly (what does Django do in this case?)

  • Wait until Django supports it (and live with bugs until then...)

It seems like the first option is the only viable one, but it's ugly, throws the baby out with the bath water, and risks missing something when a new model/relation is added.

Am I missing something? Any recommendations?

解决方案

Just a note for those who run into this issue as well, there is now an built-in solution in Django 1.3.

See the details in the documentation django.db.models.ForeignKey.on_delete Thanks for editor of Fragments of Code site to point it out.

The simplest possible scenario just add in your model FK field definition:

on_delete=models.SET_NULL

这篇关于什么是覆盖Django的级联删除行为的选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆