多对多第三张关系表
自定义多对多第三张关系表
第三张多对多关系表中设置两个关联列另外两张表的外键 上图46,47行。再在内部写上一个Meta类 上图50行
类里面写定义一个 unique_together = [('外键名1','外键名2'),] 这样就可以保证多对多联合唯一
上图46,47行设置了unique=True 表示 每一条记录中该字段的值必须唯一 也就是一对一关系
面试题 第23行 进行了切片处理 生成了一个新的列表赋值给n3
41-44 Tag表创建一个多对多的字段m to='User'表示本表与User表多对多关联 through = 'UserToTag'表示联合下面自定义的第三张关系 through_fields=['u','t']表示通过自定义的第三张表的哪些个字段是有外键关联信息 以上联合起来共同创建第三张表 (不建议使用) Tag.m.add 或 Tag.m.set 以上创建的第三张关系表 这两方法不能使用了
多对多自关联
m2m指向自己这张表 设置related_name ='b' 避免 反向查找 类名混淆的情况
user1 = models.User.objects.get(id=1)
user1.b.add(3) ---->表示在多对多自关联的表中添加一条ID为1用户 和 ID为3 用户的记录
多对多自关联表的上图后两个字段都是指向User表的id字段
ut是Person表的外键字段
从31--35总共执行了四次数据库查询 第一次是31行的.all取出所有Person表记录对象 进行for循环 35行row.ut.title并不存在于31行查询得到的每个对象内 需要再去数据库进行查询 所有每次循环 得到每个对象 每个对象还得 通过35行进行是一次数据查询 所有总共是执行4次查询操作
33行加上select_related('ut') 相当于34行的数据库查询的语句执行 那么此时38行row.ut.title的数据就存在与person_list这个QuerSet集合里的每个记录对象里了
33行多添加了一个'te' 它是Person表另外一个外键字段指向了第三张表 同样的33行就相当于34行sql语句进行了三表联合操作
同样的 39行row.te.title对象也被33行一次性的全部取出存在每个记录对象内 所有上面两图不同于上上图 它们值进行了一次数据库查询操作 也就是33行.all()是执行的
annotate是对前面values('u_id')进行group by distinct是对前面values('ut_id')进行去重
42和43行返回结果一样 因为 reverse()前面并没有order_by() 也就是说reverse()只会对order_by('id','name')内部的参数进行反转 成 order_by('-id','-name') order_by填两个参数 当一个两条记录第一个参数(字段值)相同时 比较第二个参数(字段值)
上图only方法返回的是一个每个元素都是单个对象的QuerySet集合 only方法接受的两个参数会作为 此中对象的两个属性
所有再取值时 直接使用 obj.username获取数据 obj.xxx 当xxx不存在only方法所接受的参数时 会再进行一次数据查询操作
vlues('username','id')这个方法返回的是每个元素都是字典的QuerySet集合
using方法默认参数是default 当SETTING 里 DATABASES 添加了一个default1数据库时 using方法的参数可以改成using('default1') 在使用数据库查询时就会使用default1这个数据库了
当执行函数时 2-9代码已经进行了编译 且划分好了作用域 11行返回的是inner函数 12行执行result接受的函数
但此时 inner的作用域如上图所示 当inner函数的作用域没有V值时会向外查找 当外层的函数也没有V值时 再想更外层查找
69行函数的this是windown对象
that.Name并不存在于 inner这个函数作用域内 所有会往外层函数找 外层 this = that 就是把obj对象赋值给that obj对象是有Name属性的 所有 inner函数输出结果为‘root’
24-26行是一个创建并执行的函数写法 由于这个函数并不是像21行那样赋值给obj对象 所以这个函数的this就是windown
最后30输出的结果为 先23行打印的 'alex',666 然后25行打印的windonw全局变量 'root',18