ORM表多对多的操作-创新互联

了解学习下表的多对多的操作练习

创新互联专注于企业网络营销推广、网站重做改版、百色网站定制设计、自适应品牌网站建设、H5高端网站建设成都做商城网站、集团公司官网建设、成都外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为百色等各大城市提供网站开发制作服务。

创建表结构

class Girls(models.Model):
    nick = models.CharField(max_length=32)

class Boy(models.Model):
    name = models.CharField(max_length=32)

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girls ')

添加数据

 obsboy=[
        models.Boy(name='张三封'),
        models.Boy(name='李东宝'),
        models.Boy(name='郭三贴'),
        models.Boy(name='刘能'),
    ]
    models.Boy.objects.bulk_create(obsboy,5)

    obsgirl=[
        models.Girls(nick='小红'),
        models.Girls(nick='小蓝'),
        models.Girls(nick='小绿'),
        models.Girls(nick='小紫')
    ]
    models.Girls.objects.bulk_create(obsgirl,4)

        models.Love.objects.create(b_id=1,g_id=2)
    models.Love.objects.create(b_id=2,g_id=3)
    models.Love.objects.create(b_id=3,g_id=1)
    models.Love.objects.create(b_id=4,g_id=4)
    models.Love.objects.create(b_id=1,g_id=4)

通过浏览器访问test页面,执行数据插入

查询

查询张三封的对应的女孩的名字列表
第一种方法:

select_result = models.Boy.objects.filter(name='张三封').first()
    select_loveinfo = select_result.love_set.all()# 这里通过表明+set方法反向查找
    for item in select_loveinfo:#循环的时候就跨表了
        print(item.g.nick)

第二种方法:

objs = models.Love.objects.filter(b__name='张三封')
    for row in objs:#循环的时候就跨表了
        print(row.g.nick)

第三种方法:

objs = models.Love.objects.filter(b__name='张三封').values('g__nick')#查询的时候就指定了,减少了查询次数
    for row in objs:
        print(row['g__nick'])

第四种方法:

objs = models.Love.objects.filter(b__name='张三封').select_related('g')
    for row in objs:
        print(row.g.nick)

第五中方法:

objs = models.Love.objects.filter(b__name='张三封').prefetch_related('g')
    for row in objs:
        print(row.g.nick)

添加约束条件

加上联合索引,就不能多次关联,(约会了)

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girls')
    class Meta:
        unique_together = [
            ('b','g'),
        ]

django自带生成多对多的表

上面的案例是我们手动去生成了一个关系表,来关联多个表。django可以自动给生成一个多对多的关系表
首先我们班上面的Love表注释掉。然后让django来自动创建

class Girls(models.Model):
    nick = models.CharField(max_length=32)
    m = models.ManyToManyField('Boy')#这一句diango就可以帮忙生成一个关系表。这个语句写到任何一个关联表里面都可以,如下面Boy表里面的m

class Boy(models.Model):
    name = models.CharField(max_length=32)
    #m = models.ManyToManyField('Girls')

创建上面的代码后,执行makemigrations和migrate,来生成表,然后可以看到生成了一个表,如下图
ORM表多对多的操作

给第三张表插入数据

由于没有第三张表对应的类,所以不能直接操作第三张表。所以我们也间接的去操作。
首先我们从Boy表里面取一个值,然后根据这个对象和这个表里面的m来连接到第三张表里面,如下:给第三张表添加数据

 obj = models.Boy.objects.filter(name='张三封').first()
    print(obj.id,obj.name) #这里可以看到name为“张三封”对应的id值
obj = models.Boy.objects.filter(name='张三封').first()
    print(obj.id,obj.name)# 通过对象 然后m来关联第三张表
    obj.m.add(3)#通过add来给第三张表添加数据

可以看到对应“张三封”的id对应的girls的id添加到了第三张表里面
ORM表多对多的操作

add可以添加多个值,也可以添加列表eg:obj.m..add(2,4)或者obj.m.add(*[1,3,5,])

第三张表的删除

删除使用obj.m.remove(*args,),值可以是单个值,也可以是多个或者是列表

第三张表的修改

修改使用的是obj.m.set(*args),值是必须能迭代的值,可以是列表。set是重置的,会把所有的都弄成set的值

第三张表的获取

obj = models.Boy.objects.filter(name='张三封').first()
    print(obj.id,obj.name)
    q = obj.m.all()#这里获取的是girl表的对象,也就是另外一个表的对象。只有类才可以生成对象
    print(q)#这里可以看到是girl的对象
    for xx in q:
        print(xx.nick)

ORM表多对多的操作

q = obj.m.filter(id='1'),这里也可以继续筛选,
q = obj.m.clear(),这个是吧和张三封有关的都全部清除了

反向查找

多对多也是可以反向查找的通过小写的表名字+set

obj = models.Girls.objects.all().filter(nick='小绿').first()
    q = obj.boy_set.all()
    print(q)

ORM表多对多的操作

如果想要第三张表更加灵活,要自定义,如果对第三张表以后不会增加列,就可以用django 自带的

自带和自定义的联合使用

在设计的时候使用了自带的manytomany的同时,自己也要设计第三张表。这个时候要给manytomany来设置一些参数,如下
ORM表多对多的操作

这里面添加了参数就不会生成第四张表。如果不加这个参数through,就会出现一共4张表的.这个时候,不能使用第
三张表的m.add(1)来添加,会有下面的报错:(clear,all可以,但是set,remove,add都是不可以的)
ORM表多对多的操作
ORM表多对多的操作

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享名称:ORM表多对多的操作-创新互联
当前网址:http://scyanting.com/article/doshej.html