1.创建关系表
class Boy(models.Model):
name = models.CharField(max_length=16)
class Girl(models.Model):
nick = models.CharField(max_length=16)
#创建多对多的关系表
class Love(models.Model):
b = models.ForeignKey("Boy")
g = models.ForeignKey("Girl")
#除外键外,创建其他的约束关系(联合索引or联合唯一索引)注意语法结构!
class Meta: #定义关系类,固定写法
#创建联合唯一索引
unique_together=[ #关系类型 = [("别名1","别名2"),] #列表,元素是元组
("b","g"),
],
#创建联合索引
index_together=[
("c","d"),
]
操作:
#批量增加数据
objs = [
models.Boy(name="小张"),
models.Boy(name="小王"),
models.Boy(name="小李"),
models.Boy(name="小宋"),
]
models.Boy.objects.bulk_create(objs,5)
obs = [
models.Girl(nick="小红"),
models.Girl(nick="小黄"),
models.Girl(nick="小绿"),
models.Girl(nick="小紫"),
]
models.Girl.objects.bulk_create(obs,5)
objs = [
models.Love(b_id=1,g_id=1),
models.Love(b_id=1,g_id=2),
models.Love(b_id=1,g_id=3),
models.Love(b_id=2,g_id=1),
models.Love(b_id=2,g_id=2),
]
models.Love.objects.bulk_create(objs,5)
#连表操作,查找与小张有过关联的女生
#字典类型的数据
love_list = models.Love.objects.filter(b__name="小张").values("g__nick")
for item in love_list:
print(item["g__nick"])
#对象类型的数据
love_lists = models.Love.objects.filter(b__name="小张").select_related("g")
for obj in love_lists:
print(obj.g.nick)
2.通过django自带功能ManyToManyField,完成多对多关系的关联 (任意表添加,但局限性太大)
- 创建表的过程中,不再写关系表,而是对某个表中添加关联信息,django会自动创建一个以主键为准的信息关联表
(表格式:项目名_小写表名_自定义名)。
特别注意:表内的数据结构是固定的,如果除了建立多对多的关系外还需要记录其他的数据,
则该表无法插入新的列,以至于无法完成你的要求!
- 类内定义的方式:
自定义名 = models.ManyToManyField("要关联的类名")
1)创建表:
class Boy(models.Model):
name = models.CharField(max_length=16)
m = models.ManyToManyField("Girl") #多对多,django会自动创建一个新表,用以存放多对多关系。
class Girl(models.Model):
nick = models.CharField(max_length=16)
2)表操作:
#哪个表建立的关系,就先从这个表操作。
# 先获取boy对象
obj = models.Boy.objects.filter(name="小张").first()
#通过多对多的名,对第三张关系表进行操作!
# 添加数据
obj.m.add(1) #添加一个数据
obj.m.add(2,3) #添加多个数据
obj.m.add(*[4,]) #以列表形式添加
#删除
obj.m.remove(1)
obj.m.remove(2,3)
obj.m.remove(*[4,])
#重置 #把当前对象的数据清空,再重新写入
obj.m.set([1,])
#查询全部 -->已经完成了跨表 跨到了女生表
q = obj.m.all()
print(q) #查看拿到的数据类型及所属对象,发现全是gril表的对象
for item in q:
print(item.nick) #获取每个对象的名称
#过滤查找
girl_list = obj.m.values("nick").filter(nick="小红").first()
print(girl_list)
#反向跨表,通过女生找到约会过的男生
obj = models.Girl.objects.values("id","nick","boy__name").filter(nick="小红")
print(obj)
#清表 把关系表内的数据全部清除
obj.m.clear()
3.自定义表与django自带功能ManyToManyField合用(杂交):
1)创建表:
class Boy(models.Model):
name = models.CharField(max_length=16)
m = models.ManyToManyField("Girl",through="Love",through_fields=("b","g",))
#指定通过哪个表连接,用哪几列进行关联!
class Girl(models.Model):
nick = models.CharField(max_length=16)
#创建多对多的关系表
class Love(models.Model):
b = models.ForeignKey("Boy")
g = models.ForeignKey("Girl")
#除外键外,其他的约束关系(联合索引or联合唯一索引)
class Meta:
#创建联合唯一索引
unique_together=[
("b","g"),
],
2)操作:有约束
可以通过自定义的关系表进行增删改查操作;
但是通过django自带的关系有会有约束,只能查询或是清表,其他操作会报错。
查 | 清表
obj.m.clear() 可以
v = obj.m.all()
print(v)