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. Oracle SQL调优之分区表

    目录 一.分区表简介 二.分区表优势 三.分区表分类 3.1 范围分区 3.2 列表分区 3.3 散列分区 3.4 组合分区 四.分区相关操作 五.分区相关查询 附录:分区表索引失效的操作 一.分区表 ...

  2. unite2017《Unity企业级支持案例与分析》

    在今天举办的Unite2017开发者大会上,Unity大中华区技术支持总监张黎明以"Unity企业级支持案例与分析"为主题进行了分享. 以下为演讲实录: 张黎明:非常感谢大家来参加 ...

  3. luogu P5358 [SDOI2019]快速查询【模拟(?)】

    把有单点修改和查询的点离散进一个数组,然后单点修改直接改,记录一个修改时间t,维护一个sm表示这些离散的点的和,val表示出了离散点其他点的值,因为都是一样的所以只记录这一个值即可,记录ljlc为加法 ...

  4. 2014-10-6 NOIP模拟赛

    1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行,换句话说如果计划不当可能 ...

  5. LibreOJ #2036. 「SHOI2015」自动刷题机

    #2036. 「SHOI2015」自动刷题机 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 曾经发明了信号增幅仪的发明家 SHTSC 又公开 ...

  6. IT兄弟连 JavaWeb教程 监听器4

    感知Session绑定事件的监听器 保存在Session域中的对象可以有多种状态:绑定(session.setAttribute("bean",Object)到Session中:从 ...

  7. SAP中对于获取订单的状态

    在SAP中对于如何获取订单的状态,提供了至少两个函数,分别是 STATUS_READ 和   STATUS_TEXT_EDIT.下面简单介绍这两个函数 1.STATUS_READ  改函数的实现原理大 ...

  8. pgpool-ii 安装手册 基于Centos7.3

    http://www.bkjia.com/jQuery/1173582.html地址被占用pgpool启动失败 Nov 15 02:33:56 node3 pgpool: 2016-11-15 02: ...

  9. 查找库中的某个函数,grep命令的用法。

    程序中调用了某个库中的函数,我想知道这个函数具体的作用,就必须去看这个库的源代码. 那么问题来了:如何从库中众多的.h文件中,得知我想要的函数在哪个文件里? 最后用grep命令成功解决. 具体用法:先 ...

  10. vue中做出购物车的功能

    效果展示: 一:html结构 <div id="buyButton" class="btn-buy"> <button onclick=&qu ...