title: Django models多表操作

tags: Django

多表操作

单独创建第三张表的情况

推荐使用的是使用values/value_list,selet_related的方式,查询效率高

建立表

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

class Love(models.Model):
b = models.ForeignKey('Boy')
g = models.ForeignKey('Girl') # 建立联合唯一索引
class Meta:
unique_together = [
('b','g')
]
	"""
通过第三张表查与男生表有关系的女生
下面是通过男生表反向查询 使用小写的表明love_set
"""
# obj = models.Boy.objects.filter(name='钢弹').first() # 这里是对象
# love_list = obj.love_set.all()
# for item in love_list:
# print(item.g.nick) """
通过第三张表正向操作
"""
# love_list = models.Love.objects.filter(b__name='钢弹')
# for item in love_list:
# print(item.g.nick) """
但是上面的情况是for循环多次查询,效率低,
用values,value_list进行优化,
values获得是字典,value_list获取的是元组
"""
# love_list = models.Love.objects.filter(b__name='钢弹').values('g__nick') # 仅查询一次
# print(love_list) # <QuerySet [{'g__nick': '翠花'}, {'g__nick': '英子'}, {'g__nick': '妞子'}]>
# for item in love_list:
# print(item['g__nick']) # 这是取字典内容 # love_list = models.Love.objects.filter(b__name='钢弹').values_list('g__nick')
# print(love_list)
# for item in love_list:
# print(item[0]) # 取元组中的内容 取第一个 """
使用select_related 进行优化 查询到的是一个对象
"""
# love_list = models.Love.objects.filter(b__name='钢弹').select_related('g') # 直接写外键原来的名字
# print(love_list)
# for obj in love_list:
# print(obj.g.nick) # 是通过对象查

使用ManyToManyField 创建表

使用ManyToManyField,Django会自动生成第三张表,但是没有相应的类,是不能直接操作django自动生成的表的。但是可以通过Boy表关联的m间接的进行操作。

生成的第三张表示boy_m

class Boy(models.Model):
name = models.CharField(max_length=32)
m = models.ManyToManyField("Girl") # 里面写的是要关联的表 class Girl(models.Model):
nick = models.CharField(max_length=32)

对第三张表进行增删改

 	obj = models.Boy.objects.filter(name='钢弹').first()
print(obj.id,obj.name) """
增加操作
"""
# obj.m.add(2) # 增加一个 最终增加的是g_id--> 1 2
# obj.m.add(1,2,3) # 增加多个
# obj.m.add(*[4,]) # 使用列表进行接收 """
删除操作
"""
# obj.m.remove(2)
# obj.m.remove(1,2,3)
# obj.m.remove(*[4,])

通过ManyToMany查询的,关键是通过all查询的是girl的对象

 	obj = models.Boy.objects.filter(name='钢弹').first()
print(obj.id,obj.name)
girl_list = obj.m.all() # 查询的时候Django自动获得是girl对象
print(girl_list)
for item in girl_list:
print(item.nick) # 从对象获取

还可以继续进行过滤,filter内部的字段是Girl内部的

 girl_list = obj.m.all().filter(nick='翠花') # 查询的时候Django自动获得是girl对象
for item in girl_list:
print(item.nick) # 从对象获取

修改内容

set是重置

obj.m.set([1,2])

清空clear是清空与之关联的全部

obj.m.clear()

ManyToMany的反向操作

    """
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'))
# m = models.ManyToManyField("Girl") 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')
]

使用

obj.m.clear()
obj.m.all()

中间遇到的错误,强制删除了m表

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)

Django models多表操作的更多相关文章

  1. Django ORM 多表操作

    目录 Django ORM 多表操作 表模型 表关系 创建模型 逆向到表模型 插入数据 ORM 添加数据(添加外键) 一对多(外键 ForeignKey) 一对一 (OneToOneFeild) 多对 ...

  2. Django ORM多表操作

    多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对 ...

  3. django第8天(在测试文件中运行django项目|单表操作)

    django第8天 在测试文件中运行django项目 1.将项目配置文件数据库该为mysql,修改配置信息 PORT = '127.0.0.1' DATABASES = { 'default': { ...

  4. Django之ORM表操作

    ORM表操作 1.ORM单表操作 首先想操作表的增删改查,需要先导入这个表,以之前创建的UserInfo表为例,在app下的views.py中导入 from app import models def ...

  5. Django day08 多表操作 (二) 添加表记录

    一: 一对多 1. 一对多新增 两种方式:  publish = 对象    publish_id = id 1. publish_id 和 publish 的区别就是: 1)publish_id 可 ...

  6. Django数据库数据表操作

    建立表单 django通过设置类来快速建表,打开models.py 例: from __future__ import unicode_literals from django.db import m ...

  7. Django models ORM基础操作--白话聊Django系列

    上次我们讲完了views视图,那我们这次来看一下Django强大的ORM,可以这么说,你不懂Django的ORM,你就不懂Django,那废话不多说 ORM又称关系对象映射,在ORM里,一张表就是一个 ...

  8. django ORM单表操作

    1.ORM介绍 ORM是“对象-关系-映射”的简称 映射关系: mysql---------Python 表名----------类名 字段----------属性 表记录--------实例化对象 ...

  9. Django models 单表查询

    从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet 1. 查看Django QuerySet执行的SQL .query.__str__()或 .query属性打印执行的sql语句 ...

随机推荐

  1. MS SQL Server的LTRIM,RTRIM和TRIM函数

    在MS SQL Server 2017有了一个新函数TRIM,整合以前版本LTRIM和RTRIM. 这几个函数都是去除字符串头部后尾部的空格. DECLARE @str NVARCHAR(MAX) = ...

  2. 洛谷P2652 同花顺

    P2652 同花顺 题目背景 所谓同花顺,就是指一些扑克牌,它们花色相同,并且数字连续. 题目描述 现在我手里有n张扑克牌,但它们可能并不能凑成同花顺.我现在想知道,最少更换其中的多少张牌,我能让这 ...

  3. 背包dp

    一大波模板正在靠近 1.01背包 问题:有n件物品和一个容量为v的背包,第i件物品的费用(即体积)是w[i],价值是v[i],求解将哪些物品装入背包可使这些物品的费用和不超过背包容量,且价值总和最大. ...

  4. [Xcode 实际操作]七、文件与数据-(13)数据持久化存储框架CoreData的使用:编辑CoreData中的数据

    目录:[Swift]Xcode实际操作 本文将演示如何修改数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //引入数据持 ...

  5. Spring Boot Dubbo 构建分布式服务

    概述: 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数 ...

  6. Java-GC-标记清除算法

    ## 前置知识 静态变量在类被加载的时候分配内存.当我们启动一个App的时候,系统会创建一个进程,此进程会加载一个JVM的实例,然后代码就运行在JVM之上.也就是说类在被加载的时候,静态变量 --- ...

  7. IOS 打包提示错误(ERROR ITMS-90125: ERROR ITMS-90087: ERROR ITMS-90209:)

    提示这种错误是集成环信造成的,解决方法看环信的官方文档: 集成动态库上传AppStore 由于 iOS 编译的特殊性,为了方便开发者使用,我们将 i386 x86_64 armv7 arm64 几个平 ...

  8. linux 02 基础命令

    linux 02 基础命令 1.alias 别名 pyvip@Vip:~/demo$ alias lh="ls -lh" #将ls -lh的功能赋给lh(lh原来并没有意义)这个赋 ...

  9. LINUX中IPTABLES防火墙使用

    对于有公网IP的生产环境VPS,仅仅开放需要的端口,即采用ACL来控制IP和端口(Access Control List). 这里可以使用Linux防火墙netfilter的用户态工具 iptable ...

  10. ThinkPHP集锦

    使用frame搭建页面:不要引入静态的html文件,应该在Action的方法中填写 例:<frame name="menu" src="{:U(GROUP_NAME ...