首页 > 技术文章 > Django-多对多跨表查询

863652104kai 2019-08-15 21:29 原文

多对多跨表查询

男生表:id、姓名

女生表:id、姓名

相亲记录表:id、男生id、女生id

第一种:数据准备

class Boy(models.Model):
    bname = models.CharField(max_length=32,null=True)

class Girl(models.Model):
    gname = models.CharField(max_length=32,null=True)

class Boy2Girl(models.Model):
    b = models.ForeignKey('Boy')  # 外键关联Boy表中的id
    g = models.ForeignKey('Girl')  # 外键关联Girl表中的id

    class Meta:
        # 建立联合唯一索引
        unique_together = [
            ('b','g')
        ]

# 添加数据 
boys = [
        models.Boy(bname='aaa'),
        models.Boy(bname='bbb'),
        models.Boy(bname='ccc'),
        models.Boy(bname='ddd'),
    ]
girls = [
    models.Girl(gname='张三'),
    models.Girl(gname='李四'),
    models.Girl(gname='王二'),
    models.Girl(gname='小六'),
    ]
b2g = [
    models.Boy2Girl(b_id=1,g_id=2),
    models.Boy2Girl(b_id=1,g_id=3),
    models.Boy2Girl(b_id=1,g_id=4),
    models.Boy2Girl(b_id=2,g_id=1),
    models.Boy2Girl(b_id=1,g_id=1),
    models.Boy2Girl(b_id=3,g_id=2),
    models.Boy2Girl(b_id=4,g_id=3),
    ]
models.Boy.objects.bulk_create(boys)
models.Girl.objects.bulk_create(girls)
models.Boy2Girl.objects.bulk_create(b2g)

查询数据

# 查询boy名字为aaa的相亲对象名字
# 方式一
res = models.Boy.objects.filter(bname='aaa').first()
love_list = res.boy2girl_set.all()
for item in love_list:
    print(item.g.gname)
    
# 方式二
res = models.Boy2Girl.objects.filter(b__bname='aaa').all()
for love in res:
    print(love.g.gname)
    
# 方式三
res = models.Boy2Girl.objects.values('g__gname').filter(b__bname='aaa')
print(res)

第二种:数据准备

class Boy(models.Model):
    bname = models.CharField(max_length=32,null=True)
    g = models.ManyToManyField('Girl',null=True,related_name='xxx')  # 建立关系表,related_name作用:在反向查询时可以用来代替‘小写类名_set’

class Girl(models.Model):
    gname = models.CharField(max_length=32,null=True)

# 添加数据 
boys = [
        models.Boy(bname='aaa'),
        models.Boy(bname='bbb'),
        models.Boy(bname='ccc'),
        models.Boy(bname='ddd'),
    ]
girls = [
    models.Girl(gname='张三'),
    models.Girl(gname='李四'),
    models.Girl(gname='王二'),
    models.Girl(gname='小六'),
    ]
models.Boy.objects.bulk_create(boys)
models.Girl.objects.bulk_create(girls)

# 给boy表的aaa添加相亲对象1,2,3
res =models.Boy.objects.filter(bname='aaa').first()
res.g.add(1)
res.g.add(2,3)

# 给boy表的aaa删除相亲对象3
res =models.Boy.objects.filter(bname='aaa').first()
res.g.remove(1)

# 删除boy表的aaa的所有相亲对象
res =models.Boy.objects.filter(bname='aaa').first()
res.g.clear()

# 重设置boy表的aaa的所有相亲对象
res =models.Boy.objects.filter(bname='aaa').first()
res.g.set([2,3])

# 查询boy表的aaa的相亲对象
res =models.Boy.objects.filter(bname='aaa').first()
res.g.all()  # 返回的是一个列表里套对象

# 给Girl表的小六添加相亲对象1,2,3,4
res = models.Girl.objects.filter(name='小六').first()
res.boy_set.add(1,2,3,4)  # 或者res.xxx.add(1,2,3,4)

# 给Girl表的小六删除相亲对象1
res = models.Girl.objects.filter(name='小六').first()
res.boy_set.remove(1)  # 或者res.xxx.remove(1)

# 查询Girl表的小六的相亲对象
res = models.Girl.objects.filter(name='小六').first()
res.boy_set.all()  #  # 或者res.xxx.all(),返回的是一个列表里套对象

推荐阅读