Django默认ORM(六):多对多(M2M)操作

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)

  

 

posted @ 2017-09-22 17:26  Adamanter  阅读(685)  评论(0编辑  收藏  举报