Django之模型层-多表操作
多表操作
数据库表关系
- 一对多:两个表之间的关系一旦确定为一对多,必须在数据多的表中创建关联字段
- 多对多:两个表之间的关系一定确定为多对多,必须创建第三张表(关联表)
- 一对一:一旦两个表之间的关系确定为一对一,在两种表中任意一张表中建立关联字段unique
ORM生成关联表模型
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
# 出版社信息
# 一对多
publish = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
# 多对多
author = models.ManyToManyField(to='Author')
def __str__(self):
return self.title
class Publish(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
email = models.EmailField()
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
# 一对一
authorDetails = models.OneToOneField(to='AuthorDetails',to_field='id',on_delete=models.CASCADE)
def __str__(self):
return self.name
class AuthorDetails(models.Model):
id = models.AutoField(primary_key=True)
city = models.CharField(max_length=32)
phone = models.IntegerField()
- 创建表关系方法:
- 一对一:OneToOneField()
- 一对多:ForeignKey()
- 多对多:ManyToManyField()
- 表关系模型创建注意事项
创建关联表时不需要在关联字段后面加_id,ORM会自动加
关联表关系:一对多关系
to=表的时候可以加引号也可以不加,不加引号的话必须被关联的表在关联表上面,to_field也可以不写主键,不写的话默认是关联表的主键on_delete=models.CASCADE在一对多的时候必须要加,一对多的时候也必须要加,如果不加会报on_delete错误
null = True 允许关联字段为空
在生成表关系多对多的时候,会另外生成第三张表,不会在该表内生成
多表操作之添加记录
添加记录时先添加单表的记录(不关联其他表的表),插入时与单表插入一样。然后插入与其他表关联了的表的记录,有两种插入方式:
方式1:直接传入一个关联的键
Books.objects.create(b_name='红楼梦',price=100,author_id=1,publish_id=2)
方式2:传入一个模型对象
publish_obj = Publish.objects.filter(id='1')[0]
Books.objects.create(b_name='红楼梦',price=100,author_id=1,publish=publish_obj)
在使用关联字段的时候,可以使用字段名_id,也可以直接使用字段名,使用字段名是打印的一个模型对象,使用字段名_id的话打印的是一个关联的键
book_obj = Books.objects.filter(bid=1)[0]
print(book_obj.b_name)
print(book_obj.publish) #Publish object (2)
print(book_obj.publish.p_name) #南京出版社
print(book_obj.publish_id) # 2
绑定多对多关系
book = Publish.objects.filter(id__gt=2).delete()
cao = Author.objects.get(name='曹雪芹')
luo = Author.objects.get(name='罗贯中')
book.author.add(cao,luo)
解除多对多的关系,先找到需要解除的对象
# 参数可以是一个主键也可以是模型对象
book.author.remove(1)
清空多对多关系
book.author.clear()
获取一个模型所有的关联对象
print(book.author.all())
设置多对多关系
# set函数相当于是先清空了(clear)数据,然后再重新赋值,赋值参数是一个可迭代对象
book.author.set(列表)
跨表查询
正向查询:假设关联属性在A表中,通过A查询B对象就是属于正向查询,正向查询按字段
反向查询:假设关联属性在A表中,通过B查询A对象就是属于正向查询,反向查询按表名小写_set
基于对象查询(子查询)
- 一对多的查询
# 一对多的正向查询:查询红楼梦这本书的出版社名字
book = Book.objects.filter(title='红楼梦')[0]
print(book.publish.name)
# 一对多的反向查询:查某个出版社出版过的书籍
publish_obj = Publish.objects.get(name='南京出版社')
ret = publish_obj.book_set.all()
print(ret)
- 多对多的查询
# 多对多的正向查询:查询红楼梦这本书所有作者的名字
book = Book.objects.filter(title='红楼梦')[0]
ret = book.author.all()
print(ret)
# 多对多的反向查询:查询曹雪芹写过的书
author = Author.objects.filter(name='曹雪芹')[0]
ret = author.book_set.all()
print(ret)
- 一对一的查询
# 一对一的正向查询:查询名字为曹雪芹的所在城市
auth = Author.objects.filter(name='曹雪芹').first()
print(auth.authorDetails.city)
# 一对一的反向查询:查询在江苏的作者的名字
ad = AuthorDetails.objects.filter(city='江苏').first()
print(ad.author.name)
基于双下划线的跨表查询(join查询)
正向查询按字段,反向查询按表名小写
双下划线就相当于需要关联哪一张表,相当于sql语句中的join
一对多
# 一对多的正向查询查询红楼梦的出版社名字
# 方式1
ret = Book.objects.filter(title='红楼梦').values('publish__name')
print(ret)
# 方式2
ret = Publish.objects.filter(book__title='红楼梦').values('name')
多对多
# 查询红楼梦的作者的名字
# 方式1
ret = Book.objects.filter(title='红楼梦').values('author__name')
print(ret)
# 方式2
ret = Author.objects.filter(book__title='红楼梦').values('name')
一对一查询
# 查询曹雪芹所在的城市
# 正向查询
ret = Author.objects.filter(name='曹雪芹').values('authorDetails__city')
# 反向查询
ret = AuthorDetails.objects.filter(author__name='曹雪芹').values('city')
# print(ret)
连续跨表查询
# 手机号以15开头的作者出版过的书籍以及出版社的名称
# 正向查询
ret = Book.objects.filter(author__authorDetails__phone__startswith=151).values('title','publish__name')
# 反向查询
ret = Author.objects.filter(authorDetails__phone__startswith='151').values('book__title','book__publish__name')
print(ret)
聚合查询
aggregate()函数
# 查询所有书籍的平均价格
# 聚合查询:聚合函数aggregate
from django.db.models import Avg,Max,Min,Count,Sum
ret = Book.objects.all().aggregate(Avg('price')) #返回值是一个字典
print(ret)
分组查询
annotate()
单表分组
单表分组查询的ORM语法:单表模型.objects.values('group by字段').annotate(聚合函数("统计字段")
from django.db.models import Avg,Max,Min,Count,Sum
ret = Emp.objects.values('dep').annotate(avg_salary=Avg('salary'))
print(ret)
多表分组查询
多表查询分组语句模型:
每一个后表模型.objects.value('主键').anntota(聚合函数(关联表__ 字段)).values('表模型字段以及所有统计字段')
# 查询出版社名称以及出版社出版的书籍数量
# 方式1
ret = Publish.objects.values('name').annotate(count=Count('book__title'))
print(ret)
# 方式2
ret = Publish.objects.values('id').annotate(count=Count('book__title')).values('name','count')
print(ret)
# 查询每一个作者出版过的书籍的最高价格
ret = Author.objects.values('id').annotate(max_price = Max('book__price')).values('name','max_price')
print(ret)
F 与 Q查询
- F查询
用于在一张表内两个字段进行比较查询,F对象内放的是同一张表的字段,对表进行批量操作也可以使用该类
from django.db.models import F
# 查询评论数大于阅读数
ret = Book.objects.filter(comment_num__gt=F("reda_num"))
# 所有书籍的价格加10
Book.objects.all().update(price=F('price')+10)
- Q查询
filter()等方法中的关键字参数查询都是一起进行‘AND'的,如果需要执行更复杂的查询,可以使用Q对象
Q对象可以使用&、|、~操作符组合起来使用并且可以使用括号进行分组编写任意复杂的Q对象
查询名字是红楼梦的书籍或者价格大于20元的书籍
from django.db.models import F,Q
ret = Book.objects.filter(read_num__gt=F('comment_num'))
print(ret)
ret = Book.objects.filter(Q(title='红楼梦')|Q(price__gt=20))
print(ret)
Django之模型层-多表操作的更多相关文章
- 第五章、Django之模型层---单表操作
目录 第五章.Django之模型层---单表操作 一.ORM查询 二.Django测试环境搭建 三.单表查询 1. 增 2. 改 3. 删 4. 查 第五章.Django之模型层---单表操作 一.O ...
- Django之模型层:表操作
目录 Django之模型层:表操作 一.ORM简介 django测试环境搭建 Django终端打印SQL语句 二 单表操作 2.1 按步骤创建表 2.2记录 三.多表操作 1 创建模型 2 添加.删除 ...
- 05 Django之模型层---单表操作
一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- 06 Django之模型层---多表操作
一 创建模型 表和表之间的关系 一对一.多对一.多对多 ,用book表和publish表自己来想想关系,想想里面的操作,加外键约束和不加外键约束的区别,一对一的外键约束是在一对多的约束上加上唯一约束. ...
- Django之模型层-单表操作
单表操作 添加记录 方式1 # 先实例化models中的对象,按照定义的语句规则传入参数,然后使用对象调用save()保存到数据库 book_obj = Book(id=1,title='python ...
- 第五章、Django之模型层----多表查询
目录 第五章.Django之模型层----多表查询 一.一对多字段增删改查 1.增 2.查 3.改 4. 删除 二.多对多的增删改查 1. 增 2. 改 3. 删 三.ORM跨表查询 四.正反向的概念 ...
- Django模型层-单表操作
ORM介绍 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
- Django之django模型层一单表操作
一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- Django模型层-多表操作
多表操作 一.创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是 ...
随机推荐
- mysql索引简单分析
索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将对整个表进 ...
- Mysql计算并保留两位小数
如:123456.789 转成 123456.79 自动,));
- vim : Depends: vim-common (= 2:7.4.052-1ubuntu3.1) but 2:7.4.273-2ubuntu4 is to be installed
sudo apt-get purge vim-commonsudo apt-get updatesudo apt-get upgradesudo apt-get install vim
- linux 用户/群组/权限
mv 原文件名 新文件名 #相当于重命名 查看文件内容相关命令 cat #查看文件全部内容 head - n #查看文件前n行内容(默认前十行) tail -n #查看文件后n行内容(默认后十行) t ...
- 对仿真glbl.v文件的理解
Simulation, UniSim, SimPrim - How do I use the "glbl.v" module in a Verilog simulation? De ...
- 从命令行模式运行Windows管理工具。
从命令行模式运行Windows管理工具. 分类: Play Windows 2004-08-06 16:39 6076人阅读 评论(3) 收藏 举报 1.可以直接在开始-〉运行里面输入的管理工具: 文 ...
- capjoint中的tel3核心代码teleseis3.f90
为了加入更多层的模型 将 teleseis3.f90 /home/capjoint-master/src/tel3/teleseis3.90的地层模型读取部分改为: program test PARA ...
- 牛客练习赛 23 C 托米的位运算
链接:https://www.nowcoder.com/acm/contest/156/C来源:牛客网 托米完成了1317的上一个任务,十分高兴,可是考验还没有结束 说话间1317给了托米 n 个自然 ...
- Java语法基础学习DaySix
一.JavaBean——可重用组件 1.JavaBean是指符合以下标准的Java类: (1)类是公共的 (2)有一个无参的公共的构造器 (3)有属性,且有对应的get.set方法 2.好处 用户可以 ...
- <spark入门><Intellj环境配置><scala>rk入门><Intellj环境配置><scala>
# 写在前面: 准备开始学spark,于是准备在IDE配一个spark的开发环境. 嫌这篇格式不好的看这里链接 用markdown写的,懒得调格式了,么么哒 # 相关配置: ## 关于系统 * mac ...