Django外键的删除

作者:我就是个世界 发表于:2011-06-24
Django 1.3版本以后,对models外键进行了扩展,记得之前models的外键删除,都是级联删除的,举个例子好理解:Cateogry和Blog关系,Cateory有多个Blog,所以常常在Blog实体里新建一个category的外键,当我们删除一个Category的时候,归属该Category的所有Blog,同时都被删除了,这就是级联删除了。
[separator]
有个题外话,Django的models和底层的数据库联系很密切,models之间创建的关联,都直接映射到数据库,是真正的物理关联,个人觉得这种方式,有利有弊,好的方面就是更好保持了数据的一致性;感觉不好的是,这样数据库的表之间都建立物理关联,开发过程中建立models的时候,最好想好了表的关联,不然后面models加关联,需要在数据库上手动去关联,而且如果想在数据库操作数据的时候,需要考虑这些关联,不然你可能遇到一些关联的问题。在Rails上,这点都是在程序级上定义models关联,数据库并没有是正的物理关联。既然要用Django,应该先抛开这些,接受它的设计理念,才不会有困惑。

Django 1.3 models之间关联还是保存原来的做法,当你删除一个外键的时候,外键关联的实体也被删除,但在创建models的时候,外键增加了一个可选参数on_delete。今天看看它的用法:
[code]
class Blog(models.Model):
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
...
[/code]

当blog对应的user被删除了,blog里的user字段会设置为空值,而不是连同blog也删除掉,这点比原先的进了一小步,有点选择性了。当然,如果没有指定on_delete,Django还是采用级联的删除方式。

on_delete有多少个选项呢:
CASCADE:这就是默认的选项,级联删除,你无需显性指定它。
PROTECT: 保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。
SET_NULL: 置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。
SET_DEFAULT: 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
SET(): 自定义一个值,该值当然只能是对应的实体了,看一下代码:
[code]
def get_sentinel_user():
    return User.objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))
[/code]

以上的代码,当删除mymodel对应的user的时候,mymodel不会删除掉,而是找到一个名叫 deleted的user,与之重建关联。

分享:

扫一扫在手机阅读、分享本文

请发表您的评论