Django models多表操作
单独创建第三张表的情况
推荐使用的是使用values/value_list,selet_related的方式,查询效率高
建立表
1 2 3 4 5 6 7 8 9 10 11
| class Boy(models.Model): name = models.CharField(max_length=32) class Girl(models.Model): nick = models.CharField(max_length=32) class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl')
|
表建立联合唯一索引unique_together
1 2 3 4 5 6 7 8 9
| class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') class Meta: unique_together = [ ('b','g') ]
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| """ 通过第三张表查与男生表有关系的女生 下面是通过男生表反向查询 使用小写的表明love_set """ """ 通过第三张表正向操作 """ """ 但是上面的情况是for循环多次查询,效率低, 用values,value_list进行优化, values获得是字典,value_list获取的是元组 """ """ 使用select_related 进行优化 查询到的是一个对象 """
|
使用ManyToManyField 创建表
使用ManyToManyField,Django会自动生成第三张表,但是没有相应的类,是不能直接操作django自动生成的表的。但是可以通过Boy表关联的m间接的进行操作。
生成的第三张表示boy_m
1 2 3 4 5 6 7
| class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField("Girl") class Girl(models.Model): nick = models.CharField(max_length=32)
|
对第三张表进行增删改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| obj = models.Boy.objects.filter(name='钢弹').first() print(obj.id,obj.name) """ 增加操作 """ """ 删除操作 """
|
通过ManyToMany查询的,关键是通过all查询的是girl的对象
1 2 3 4 5 6
| obj = models.Boy.objects.filter(name='钢弹').first() print(obj.id,obj.name) girl_list = obj.m.all() print(girl_list) for item in girl_list: print(item.nick)
|
还可以继续进行过滤,filter内部的字段是Girl内部的
1 2 3
| girl_list = obj.m.all().filter(nick='翠花') for item in girl_list: print(item.nick)
|
修改内容
set是重置
清空clear是清空与之关联的全部
ManyToMany的反向操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| """ ManyToMany的反向操作 小写的表名_set.all() 通过Girl取Boy """ obj = models.Girl.objects.filter(nick='翠花').first() boy_list = obj.boy_set.all() print(boy_list) for item in boy_list: print(item.name) `` ManyToMany的缺陷是只能自动创建3列字段,不能再进行扩展。所以用到了下面的混合使用 不影响第三张表的使用,第三张表还是通过类进行增加删除 通过ManyToMany增加的是**查询和清空**的功能 **关键是 through through_fields**,through指定的是自己创建的第三张表, through_fields指定的是第三张表中的字段 这样就指定了自己创建第三张表,不通过ManyToMany创建 ```python class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField("Girl",through='Love',through_fields=('b','g')) class Girl(models.Model): nick = models.CharField(max_length=32) class Love(models.Model): b = models.ForeignKey('Boy') g = models.ForeignKey('Girl') class Meta: unique_together = [ ('b','g') ]
|
使用
1 2
| obj.m.clear() obj.m.all()
|
中间遇到的错误,强制删除了m表
1 2
| ValueError: Cannot alter field app01.Boy.m into app01.Boy.m - they are not compatible types (you cannot alter to or from M2M fields, or add o r remove through= on M2M fields)
|