字段关系
多对多(ManyToManyField)
多对多关系存在于两个或两个以上的数据表中,第一个表的某一行数据可以与第二个表的一到多行数据进行关联,同时在第二个表中的某一行数据也可以与第一个表的一多行数据进行关联。多对多字段可定义在任意一方。
基本原则:
多对多的表,则必须设中间关联表,关联表设独立主键,并引入两个“多”头的表的主键作为关联表的外键。
格式:
models.ManyToManyField(‘<主表>’)
创建表
两种方法,一个是利用Django自动为多对多创建关联的第三张表,另一种是自己手动创建关系表。
1、根据Django中的代码,自动为多对多表创建一个第三张表对应关系
采用默认中间表的数据库结构:
<中间表id> <多对多表>_id <主表>_id
默认中间表通过保存两张表的id进行关联
例如: 创建一个经典的多对多关系:一本书可以有多个作者,一个作者可以有多本书.
from django.db import models # Create your models here. # 创建一个经典的多对多关系:一本书可以有多个作者,一个作者可以有多本书 class Author(models.Model) name = models.CharField(max_length=20) email = models.EmailField() class Book(models.Model) title = models.CharField(max_length=60) authors = models.ManyToManyField(Author)
2、自己手动创建关系表。
采用自定义中间表并添加新字段的数据库结构:
<中间表id> <新字段1> <新字段2> <多对多表>_id <主表>_id
models.py
class Author(models.Model) name = models.CharField(max_length=20) email = models.EmailField() class Book(models.Model) title = models.CharField(max_length=60) authors = models.ManyToManyField(Author) class HostRelation(models.Model): c1 = models.ForeignKey(Author) c2 = models.ForeignKey(Book)
view.py
#多对多自定义创建表 models.HostRelation.objects.create( c1=models.Author.objects.get(id=1), c2=models.Book.objects.get(id=2) ) models.HostRelation.objects.create( c1_id=2, c2_id=1 )
through 参数
用被关联的模型的小写名称的复数形式做为ManyToMany字段的名.当两个模型都存在多对多关系,而需求是要了解更多其中的细节,那我们可以借助 through 参数,使他转向一个中介模型。
自定义中间表,用于保存两表关系的附加数据,中间表要有两个外键字段分别指向关联的两个模型。
through_fields=(<字段1>, <字段2>)
当中间表有多个外键指向一个表的时候,用through_firlds指定中间表的两个连接字段,
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> #获取字段信息