Django models多表操作
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多表操作的更多相关文章
- Django ORM 多表操作
目录 Django ORM 多表操作 表模型 表关系 创建模型 逆向到表模型 插入数据 ORM 添加数据(添加外键) 一对多(外键 ForeignKey) 一对一 (OneToOneFeild) 多对 ...
- Django ORM多表操作
多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对 ...
- django第8天(在测试文件中运行django项目|单表操作)
django第8天 在测试文件中运行django项目 1.将项目配置文件数据库该为mysql,修改配置信息 PORT = '127.0.0.1' DATABASES = { 'default': { ...
- Django之ORM表操作
ORM表操作 1.ORM单表操作 首先想操作表的增删改查,需要先导入这个表,以之前创建的UserInfo表为例,在app下的views.py中导入 from app import models def ...
- Django day08 多表操作 (二) 添加表记录
一: 一对多 1. 一对多新增 两种方式: publish = 对象 publish_id = id 1. publish_id 和 publish 的区别就是: 1)publish_id 可 ...
- Django数据库数据表操作
建立表单 django通过设置类来快速建表,打开models.py 例: from __future__ import unicode_literals from django.db import m ...
- Django models ORM基础操作--白话聊Django系列
上次我们讲完了views视图,那我们这次来看一下Django强大的ORM,可以这么说,你不懂Django的ORM,你就不懂Django,那废话不多说 ORM又称关系对象映射,在ORM里,一张表就是一个 ...
- django ORM单表操作
1.ORM介绍 ORM是“对象-关系-映射”的简称 映射关系: mysql---------Python 表名----------类名 字段----------属性 表记录--------实例化对象 ...
- Django models 单表查询
从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet 1. 查看Django QuerySet执行的SQL .query.__str__()或 .query属性打印执行的sql语句 ...
随机推荐
- MS SQL Server的LTRIM,RTRIM和TRIM函数
在MS SQL Server 2017有了一个新函数TRIM,整合以前版本LTRIM和RTRIM. 这几个函数都是去除字符串头部后尾部的空格. DECLARE @str NVARCHAR(MAX) = ...
- 洛谷P2652 同花顺
P2652 同花顺 题目背景 所谓同花顺,就是指一些扑克牌,它们花色相同,并且数字连续. 题目描述 现在我手里有n张扑克牌,但它们可能并不能凑成同花顺.我现在想知道,最少更换其中的多少张牌,我能让这 ...
- 背包dp
一大波模板正在靠近 1.01背包 问题:有n件物品和一个容量为v的背包,第i件物品的费用(即体积)是w[i],价值是v[i],求解将哪些物品装入背包可使这些物品的费用和不超过背包容量,且价值总和最大. ...
- [Xcode 实际操作]七、文件与数据-(13)数据持久化存储框架CoreData的使用:编辑CoreData中的数据
目录:[Swift]Xcode实际操作 本文将演示如何修改数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //引入数据持 ...
- Spring Boot Dubbo 构建分布式服务
概述: 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的调用次数 ...
- Java-GC-标记清除算法
## 前置知识 静态变量在类被加载的时候分配内存.当我们启动一个App的时候,系统会创建一个进程,此进程会加载一个JVM的实例,然后代码就运行在JVM之上.也就是说类在被加载的时候,静态变量 --- ...
- IOS 打包提示错误(ERROR ITMS-90125: ERROR ITMS-90087: ERROR ITMS-90209:)
提示这种错误是集成环信造成的,解决方法看环信的官方文档: 集成动态库上传AppStore 由于 iOS 编译的特殊性,为了方便开发者使用,我们将 i386 x86_64 armv7 arm64 几个平 ...
- linux 02 基础命令
linux 02 基础命令 1.alias 别名 pyvip@Vip:~/demo$ alias lh="ls -lh" #将ls -lh的功能赋给lh(lh原来并没有意义)这个赋 ...
- LINUX中IPTABLES防火墙使用
对于有公网IP的生产环境VPS,仅仅开放需要的端口,即采用ACL来控制IP和端口(Access Control List). 这里可以使用Linux防火墙netfilter的用户态工具 iptable ...
- ThinkPHP集锦
使用frame搭建页面:不要引入静态的html文件,应该在Action的方法中填写 例:<frame name="menu" src="{:U(GROUP_NAME ...