Django外键的删除

Django 1.3版本以后,对models外键进行了扩展,记得之前models的外键删除,都是级联删除的,举个例子好理解:Cateogry和Blog关系,Cateory有多个Blog,所以常常在Blog实体里新建一个category的外键,当我们删除一个Category的时候,归属该Category的所有Blog,同时都被删除了,这就是级联删除了。

有个题外话,Django的models和底层的数据库联系很密切,models之间创建的关联,都直接映射到数据库,是真正的物理关联,个人觉得这种方式,有利有弊,好的方面就是更好保持了数据的一致性;感觉不好的是,这样数据库的表之间都建立物理关联,开发过程中建立models的时候,最好想好了表的关联,不然后面models加关联,需要在数据库上手动去关联,而且如果想在数据库操作数据的时候,需要考虑这些关联,不然你可能遇到一些关联的问题。在Rails上,这点都是在程序级上定义models关联,数据库并没有是正的物理关联。既然要用Django,应该先抛开这些,接受它的设计理念,才不会有困惑。

Django 1.3 models之间关联还是保存原来的做法,当你删除一个外键的时候,外键关联的实体也被删除,但在创建models的时候,外键增加了一个可选参数on_delete。今天看看它的用法:

  1. class Blog(models.Model):  
  2. user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)  
  3. ...  
当blog对应的user被删除了,blog里的user字段会设置为空值,而不是连同blog也删除掉,这点比原先的进了一小步,有点选择性了。当然,如果没有指定on_delete,Django还是采用级联的删除方式。

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

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


==================================================================

在已经建好的model(数据库)中增加外键作为新的字段:

作为外键的model为(该model从数据库中自动产生):
class People(models.Model):
name = models.TextField(primary_key=True, blank=True) # This field type is a guess.
entrance_date = models.TextField(blank=True) # This field type is a guess.
entrance_semester = models.TextField(blank=True) # This field type is a guess.
degree = models.TextField(blank=True) # This field type is a guess.
phone_number = models.TextField(blank=True) # This field type is a guess.
email = models.TextField(blank=True) # This field type is a guess.
qq = models.TextField(blank=True) # This field type is a guess.
remarks = models.TextField(blank=True) # This field type is a guess.
def __unicode__(self): 
return self.name
class Meta:
db_table = u'people'

另一Model(Equipment)追加一个字段:
lab_user = models.ForeignKey(People)

数据库(sqlite3)中新加入一个字段:
alter table 'equipment' add 'lab_user_id';
赋值:
update equipment set lab_user_id = '张山';

若要被search到,search_fields 中添加 lab_user__name 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值