美文网首页Django+小程序
Django学习笔记:Models03 关系类型字段

Django学习笔记:Models03 关系类型字段

作者: Py_Bird | 来源:发表于2018-12-24 13:59 被阅读28次

多对一(ForeignKey)

多对一关系由外键实现,外键要定义在“多”的一方,如:

models.ForeignKey(<主表>, ...)

如果要关联的主表在另一个app中,要显式的指出:

models.ForeignKey(’<app名称>.<主表>‘, ...)

 

可创建自己关联自己的外键——比如,在评论系统中,一条评论可被多次引用自身并继续评论:

class Comment(models.Model):

    title = models.Charfield(max_length=128)

    text = models.TextField()

    parent_comment = models.ForeignKey(’self’, on_delete=models.CASCADE)

    ...

如果在子模型中存在多个外键指向同一个主模型,必须给他们加上不同的related_name,用于反向查询。

外键字段在数据库中的列名是<外键名>_id,用来储存主表对象的id,因此,在得到主表id的情况下可以不调用外键而直接筛选:

QuerySet = <外键表>.filter(<外键名>_id=<主表id>)

#获得与“<主表id>=xxx的主对象”相关联的子对象

多对一的字段参数

on_delete=models.XXX

当主对象被删除时,关联的子对象的操作(因为主键不能随意删除,外键可以直接删除)

models.CASCADE:同时删除关联的子对象,Django默认

models.PROTECT:阻止CASCADE删除关联的子对象,并弹出ProtectedError异常

models.SET_NULL:将子对象的外键字段设为null(外键字段需设置null=True)

models.SET_DEFAULT:将子对象的外键字段设为默认值(外键字段需设置default=’xxx’)

models.DO_NOTHING:什么也不做

models.SET():设置为一个传递给SET()的值或一个回调函数的返回值

注:on_delete是Django2.0之后新增的必选项。

related_name= 

通过主对象反向引用子对象的通道名称,默认名称是<小写子模型名>_set。

如:

class Car(models.Model):

    factory = models.ForeignKey(

        Factory,      

        on_delete=models.CASCADE,

        related_name='car_by_factory',

    )

此时Factory主表取出所有关联的Car对象:factory.car_by_factory.all()

如果不想给外键设置反向关联名称,就用related_name=’+’或以+号结尾

related_query_name= 

主对象反向关联查询的名称,默认查询名称是<外键列>__<主表的某列>。

如:

class Tag(models.Model):

    article = models.ForeignKey(

        Article,

        on_delete=models.CASCADE,

        related_query_name="tag",

    )

    name = models.CharField(max_length=255)

此时用tag作为查询名称:Article.objects.filter(tag__name="A")

limit_choices_to={}

限制外键能关联的对象,用于Django的表单模块和admin后台,可以传入字典、Q对象、一个返回字典或Q对象的函数。

如:

staff_member = models.ForeignKey(

    User,

    on_delete=models.CASCADE,

    limit_choices_to={'is_staff': True},

)

此时,表单模块的staff_member字段列表中只会出现is_staff=True的Users对象,对admin后台非常有用。

to_field= 

让外键关联到指定的字段上(默认关联到主键),该字段必须有unique=True属性。

多对一的引用

子对象引用主对象:

<子对象>.<外键列>

主对象引用子对象:

<主对象>.<子表小写>_set

如:

<主对象>.<子表小写>_set.all()                          #所有关联子对象的集合

<主对象>.<子表小写>_set.create(<子表字段>=’xxx’, ...)     #创建关联的子对象

<主对象>.<子表小写>_set.count()                       #查询关联子对象的数量

添加多对一关系:

<子对象>.<外键列> = <主对象>

<子对象>.save()

删除多对一关系:

<子对象>.<外键列> = None     #外键列要设为null=True

多对一的查询

查询子对象的集合:

<子表>.objects.filter(<外键列>__<主表的某列>=’xxx’)

#获得与“<主表的某列>=xxx的主对象”相关联的子对象

查询主对象的集合:

<主表>.objects.filter(<子表小写> __<子表的某列>=’xxx’)

#获得与“<子表的某列>=xxx的子对象”相关联的主对象

多对多(ManyToManyField)

多对多字段可定义在任意一方,如:

models.ManyToManyField(‘<主表>’)

多对多字段不支持Django内置的validators验证功能。

null参数对ManyToManyField多对多字段无效,设置null=True毫无意义。

如果在子模型中存在多个多对多键指向同一个主模型,必须给他们加上不同的related_name,用于反向查询。

采用默认中间表的数据库结构:

<中间表id>  <多对多表>_id   <主表>_id

默认中间表通过保存两张表的id进行关联

采用自定义中间表并添加新字段的数据库结构:

<中间表id>  <新字段1>  <新字段2>  <多对多表>_id   <主表>_id

多对多字段的参数

related_name= 

主对象反向引用多对象时的名称,和多对一相同。

related_query_name= 

主对象反向关联查询的名称,和多对一相同。

through= 

自定义中间表,用于保存两表关系的附加数据,中间表要有两个外键字段分别指向关联的两个模型。

through_fields=(<字段1>, <字段2>)

当中间表有多个外键指向一个表的时候,用through_firlds指定中间表的两个连接字段,如:

class Person(models.Model):

    name = models.CharField(max_length=32)

class Group(models.Model):

    name = models.CharField(max_length=64)

    members = models.ManyToManyField(

        Person,

        through='Membership',

        through_fields=('group', 'person' ),     #指定两个连接字段

    )

class Membership(models.Model):

    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    person = models.ForeignKey(Person, on_delete=models.CASCADE)

    inviter = models.ForeignKey(                       #另一个指向Person表的外键

        Person,

        on_delete=models.CASCADE,

        related_name="membership_invites",

    )

    invite_reason = models.CharField(max_length=128)

db_table= 

设置中间表的名称,默认为<多对多字段名>_<主表名>_<一串哈希码>

limit_choices_to={ }

限制多对多键关联的对象,和多对一相同,对于用through定义中间表的字段无效。

 

多对多的引用

多对象引用主对象:

<多对象>.<多键列>

主对象引用多对象:

<主对象>.<多表小写>_set

添加多对多关系:(默认中间表)

<多对象>.<多键列>.add(<主对象>)     #可同时添加多个主对象

添加多对多关系:(自定义中间表)

a = <主对象>

b = <多对象>

membership = <中间表>(<主表外键列>=a, <多表外键列>=b, <字段1>=’xxx’, <字段2>=’xxx’, ...)

membership.save()

#先创建主表和多表的实例,再创建中间表的连接关系

#自定义中间表不能用add()、create()、remove()和set()操作对象的关系

删除多对多关系:

<多对象>.<多键列>.clear()

获取中间表的附加数据:

a = <主对象>

b = <多对象>

membership = <中间表>.objects.get(<主表外键列>=a, <多表外键列>=b)

membership.<字段1>     #获取字段信息

一对一(OneToOneField)

反向关联的对象只有一个,多数用于从一个模型扩展出另一个模型的情况。

一对一通过子对象访问关联的主对象:

<子对象>.<一对一键>

一对一通过主对象访问关联的子对象:

<主对象>.<小写子模型名>

注意返回的是单个对象而不是集合。

相关文章

  • Django学习笔记:Models03 关系类型字段

    多对一(ForeignKey) 多对一关系由外键实现,外键要定义在“多”的一方,如: models.Foreign...

  • Django关系类型字段

    简述 本文一共三大类,分别是 多对一(外键ForeignKey) 多对多(ManyToManyField) 一对一...

  • Django 字段类型

    Django关联mysql文章链接:https://www.jianshu.com/p/c09c0541a9cf

  • django:models操作

    django关于数据库的操作,使用ORM框架。以类的形式表示一个表的关系。 字段 每个表的字段类型 小结: 基本上...

  • Django学习第一天

    Django学习笔记 1.Django的安装 关于Django的版本和python的版本依赖关系,请看下图 Dja...

  • django 第四天2019-07-31

    django 关系型数据库的关系包括三种类型: ForeginKey: 一对多,将字段定义在多的一端中 ManyT...

  • Django字段类型清单

    Django字段类型清单 AutoField:自动递增的整型字段,添加记录时它会自动增长。通常不需要直接使用这个字...

  • Django - ORM字段类型

    常使用到的字段类型有: 字符串,数字,时间,二进制。 UrlField和EmailField都是字符串类型。Url...

  • Django下模型操作

    一、Django中的字段约束以及约束类型 1.常用字段约束 IntergeField:  整型 CharField...

  • django常用字段类型

    类型说明 AutoField一个自动增加的整数类型字段。通常你不需要自己编写它,Django会自动帮你添加字段:i...

网友评论

    本文标题:Django学习笔记:Models03 关系类型字段

    本文链接:https://www.haomeiwen.com/subject/qbfzkqtx.html