django ORM 外键详解

2018/07/06 14:27
阅读数 34

Django中的外键:
  首先,为了方便理解,我们把使用ForeignKey的字段所在的表定义为从表,把ForeignKey中to参数连接的表称为主表。

外键使用的先决条件:
  在mysql数据表中,数据引擎有很多种,最常用的就是InnoDB和MyISAM,只有主表和从表的数据库引擎都是InnoDB时,表与表之间才能使用外键连接

外键介绍:

  外键在django的ORM连表操作时非常常用,在django中我们使用ForeignKey作为关键词去定义外键,下面是ForeignKey的构造方法:
    def __init__(self, to, on_delete, related_name=None, related_query_name=None,limit_choices_to=None, parent_link=False, to_field=None,db_constraint=True, **kwargs):

  我们在django的ORM中定义ForeignKey时必需要传递的参数是to和on_delete,其他参数为选填,下面我们来解释一下这些参数:
    to:需要传递被外键连接的主表模型作为值,如果连接时主表模型还没定义,建议使用主表模型类名加上"",这样就不会报错
    on_delete:需要传递当主表中的一条数据删除时,从表中与这条数据相关联的数据要执行怎样的动作,注意这个参数定义的是主表上的一条数据删除时从表上与之关联的数据的动作(如果是从表上的这条数据删除则与主表上的数据无关)

    class Book(models.Model):
      name = models.CharField(max_length=64,blank=True)
      content = models.TextField(blank=True)
      pub_time = models.DateTimeField(auto_now_add=True)
      publisher = models.ForeignKey(to="Publisher",on_delete=models.SET_NULL,null=True)

    class Publisher(models.Model):
      name = models.CharField(max_length=64,blank=True)
      mobile = models.CharField(max_length=11,unique=True)

    注:如果从表中某个字段使用ForeignKey,然后这个字段没有传递db_index,django会默认为这个字段传递一个db_index=True的参数

外键的删除操作详解:
  1、models.CASCADE:级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除
  2、models.SET_NULL:当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空
  3、models.PROTECT:当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除
  4、models.SET_DEFAULT:当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值,其实这个
  class Publisher(models.Model):
    name = models.CharField(max_length=64,blank=True)
    mobile = models.CharField(max_length=11,unique=True)

  class Book(models.Model):
    name = models.CharField(max_length=64,blank=True)
    content = models.TextField(blank=True)
    pub_time = models.DateTimeField(auto_now_add=True)
    publisher = models.ForeignKey(Publisher,on_delete=models.SET_DEFAULT,null=True,
default=Publisher.objects.get(pk=2),related_name='book')

其实,default也可以是一个函数(在任意字段均可),此时可以,注意这时只传递函数名称,django在操作时会帮我们自动执行:
  def publisher():
    return Publisher.objects.get(pk=1)

  class Book(models.Model):
    name = models.CharField(max_length=64,blank=True)
    content = models.TextField(blank=True)
    pub_time = models.DateTimeField(auto_now_add=True)
    publisher = models.ForeignKey(Publisher,on_delete=models.SET_DEFAULT,null=True,
default=publisher,related_name='book')

  5、models.SET():当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数
  def publisher():
    return Publisher.objects.get(pk=1)

  class Book(models.Model):
    name = models.CharField(max_length=64,blank=True)
    content = models.TextField(blank=True)
    pub_time = models.DateTimeField(auto_now_add=True)
    publisher = models.ForeignKey(Publisher,on_delete=models.SET(publisher),null=True,related_name='book')

  6、models.DO_NOTHING:什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部