基于双下划线的跨表查询 (join查询)
因为你的数据库中的查询就是重点 那么你的django提供的orm也是查询语句最重点 ,也提供的查询方法比较的多,下面我们学习下类似于MYSQL的连表(join)查询
Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。
这个查找不论是一对一,一对多,多对多都按照:正向查找按字段(关联字段),反向查询按表名(小写)来查找
并且是基于queryset查询就必须是__而基于对象的查询的是用点 .
反向查找:就好比你要查找的信息在另外一个关联内的表然后你就要通过另外一个关联表然后来调用它的字段就是反向通过表名用字段
正向查找: 就是表示过滤的字段在你的表中 然后你就通过你的表来找到自己的字段来查找
过滤查找后再筛选你要查找的内容用value或者values__list来筛选
比如你要查找book对用的作者的名字
你的book可以直接找到关联作者的字段 authors就是直接可以找到你这个book的书名对应的作者的对象 然后再__调用名字字段就可以了
建立表
models:
from django.db import models # Create your models here. class Book(models.Model):
title = models.CharField(max_length = 30)
price = models.DecimalField(max_digits = 30,decimal_places= 2,null = True) # 最后的True代表可以为空
pub_date = models.DateTimeField()
publish = models.ForeignKey(to = 'Publish',to_field = 'id',on_delete = models.CASCADE)
authors = models.ManyToManyField(to = 'Author')
comment_count = models.IntegerField(default = 0)
up_count = models.IntegerField(default = 0)
read_count = models.IntegerField(default = 0) def __str__(self):
return self.title class Publish(models.Model):
name = models.CharField(max_length = 30)
email = models.IntegerField()
# ad = models.OneToOne
addr = models.CharField(max_length = 30) class Author(models.Model):
name = models.CharField(max_length = 30)
age = models.IntegerField()
ad = models.OneToOneField(to = 'AuthorDetial', to_field = 'id' ,on_delete = models.CASCADE) class AuthorDetial(models.Model):
gf = models.CharField(max_length =30)
tel = models.CharField(max_length = 30) class Emp(models.Model):
name = models.CharField(max_length = 30)
age = models.IntegerField()
salary = models.DecimalField(max_digits=30,decimal_places=3)
dep = models.CharField(max_length=30)
province = models.CharField(max_length = 30) class Nice(models.Model):
id = models.AutoField(primary_key = True)
name = models.CharField(max_length = 30)
models
插入信息:
def add(request):
#一对多的添加方式
# book = Book.objects.create(title = '老王转',price = 9.9, pub_date= '1989-06-17',publish_id = 1)
# print(book.title)
# publish = Publish.objects.create(name = '大中华出版社',email = 123456, addr = '中南海')
# print(publish.name)
#添加作者
# author = Author.objects.create(name = '老王',age = 17,ad_id = 1 )
# print(author.name)
#添加作者和作者女朋友信息
# authors_detical = AuthorDetial.objects.create(gf = '隔壁小妹妹', tel = 110)
# print(authors_detical.gf)
# authors_d = AuthorDetial.objects.create(gf = '操场小姐姐',tel = 119)
# print(authors_d)
# authors_id = AuthorDetial.objects.create(gf = '医院小护士',tel = 120)
# print(authors_id.gf)
#添加作者
# author = Author.objects.create(name = '柳下惠',age = 18, ad_id = 3)
# print(author.name) #添加出版社
# Publish.objects.create(name = '华北出版社',email = 23456,addr = '中华北部')
# Publish.objects.create(name = '上海出版社',email = 3456, addr = '天南海北') #添加书籍信息
# Book.objects.create(title = '智商与情商',price = 30.5, pub_date = '2017-03-15',comment_count= 300,up_count= 201,read_count= 102 ,publish_id = 2 )
# Book.objects.create(title='人民心论', price=700, pub_date='2013-08-20', comment_count=120, up_count=85,
# read_count=67, publish_id=1)
# Book.objects.create(title='愚弄', price=40, pub_date='1997-06-15', comment_count=60, up_count=11,
# read_count=400, publish_id=3) #为书籍和作者添加关系
# laowng = Author.objects.filter(name = '老王').first()
# lz = Author.objects.get(name = '柳下惠')
# book = Book.objects.get(title = '愚弄')
# book.authors.add(*[laowng,lz]) # book = Book.objects.filter(title = '人民心论').first()
# book.authors.add(laowng)
# book = Book.objects.get(title = '智商与情商')
# book.authors.add(*[lz,laowng])
连续跨表查询需要用到__下划线 然后用values来分组
连续跨表查找 这个时候就用到了关联的字段 当你正向查找的时候 这个关联的字段就好比是一个中间桥梁 可以直接通过__下划线取查找信息
#查询作者的女朋友以110开头的作者出版过的书籍的信息和出版社的名字
# ret = Author.objects.filter(ad__tel__startswith=110).values('book__title','book__publish__name')
#首先你先用正向查询查找到作者的女朋友的信息 因为书籍和作者的关系字段在书籍表内然后再用反向查找查找书籍的信息和出版社的信息
# print(ret) # 查询作者的女朋友以110开头的作者出版过的书籍的信息和出版社的名字(正向查找)
#因为用的是book表来查找就是正向查找 先用字段通过作者和女朋友的关系字段ad然后找到自己的tel然后再连接publisj
# ret = Book.objects.filter(authors__ad__tel__startswith = 110).values('title','publish__name')
# print(ret) #查询医院小护士的男朋友
# ret = Author.objects.filter(ad__gf = '医院小护士').values('name')
# print(ret) #查询愚弄这本书的作者的女朋友的手机号
# ret = Book.objects.filter(title = '愚弄').values('authors__ad__tel')
#先通过正向查询找到书名然后通过字段找到作者表和作者女朋友关系表进行关联的字段再找女朋友的信息
# print(ret)
当你正向查找的时候先找到自己表内的关联的字段 然后通过__下划线就可以直接调用要查询表中的字段名
而反向查找直接通过被查找表直接__自己的字段就可以了
#查询大中华出版社 出版过的所有的书籍和作者的信息
#反向查找
# ret = Publish.objects.filter(name = '大中华出版社').values('book__title','book__authors__name')
# print(ret)
#正向查找
# ret = Book.objects.filter(publish__name ='大中华出版社').values('title','authors__name')
# print(ret)
# #查找女朋友的手机号是以119开头的的作者出版的书籍
# ret = Author.objects.filter(ad__tel__startswith = 119).values('book__title')
# print(ret) #正向查找
# ret = Book.objects.filter(authors__ad__tel__startswith= 119).values('title')
# print(ret )
反向查找直接被查找表 __查找信息字段就可以了
聚合查询:
聚合查询 需要导入聚合函数:
from django.db.models import Avg,Count,Max,Min
导入这个信息的时候你就可以了
# #统计所有的书籍的平均价格 书籍总数书籍的最高价格
# ret = Book.objects.all().aggregate(avg = Avg('price'),count = Count(1),max_price = Max('price'))
# print(ret['avg'],ret)
#
分组查询:
annotate()来分组
#分组的单表查询 # ret = Book.objects.all().values('title')
# print(ret) #这是算出你的每个部门的平均值 #先按照values后面的内容分组然后再用annotate分组统计计算你的平均值
# ret = Emp.objects.values('dep').annotate(avg = Avg('salary'))
# print(ret) #统计每个省的总人数
#先按照省份分组然后用分组统计的函数annotate 再用求和count
# ret = Emp.objects.values('province').annotate(count = Count(1))
# print(ret) #分组的多表查询
# Publish.objects.values('id').annotate(ad = Avg('book__price') )
# print('*'*100) # ret = Publish.objects.values("id").annotate(avg=Avg("book__price"))
# #查询每一个出版社的名称以及对用的书籍的最高价格
# ret = Publish.objects.values('id').annotate(max_pri = Max('book__price')).values('name','max_pri')
# print(ret)
#这个是先用出版社的id分组 然后连表操作book和Publish然后再对你join后的表进行提取name和最大价格 #这个是求每个出版社出版的名称和出版书籍的平均价格
# ret = Publish.objects.values('id').annotate(avg = Avg('book__price')).values('name','avg')
# print(ret) #查询每个作者的名字和出版的书籍的最高价格
# ret = Author.objects.values('id').annotate(max_line = Max('book__price')).values('name','max_line')
# print(ret) #查询每一本书籍的名称以及作者的个数
# ret = Book.objects.values('id').annotate(coun = Count('authors__id')).values('title','coun') #先用书籍的id来分组 然后把两个表join起来 因为是正向查找就用到了字段然后找到连表的同时统计这个作者的个数 然后通过连后的表查找书的名字和作者的总个数
# print(ret) #其实分组的多表查询就是你先要确定哪几个表进行连接 然后对应的sql的操作是什么你要了解 然后你要找到分组的字段 然后进行判读是反向还是正向进行字段的查找 然后再对你连接后的表进行提取你想要的内容 #查询不止一个作者的书籍的名称
# ret = Book.objects.values('id').annotate(coun = Count('authors__id')).filter(coun__gt=1).values('title')
#这个就是你的 先按照书籍的id来分组然后书籍表和作者表连接 然后把作者表和书籍表连接起来 然后 统计作者的个数个数大于1的条件,然后找出名字
# print(ret)
# --- 查询每一个出版社名称以及对应书籍的平均价格
# ret = Publish.objects.values('id').annotate(av = Avg('book__price')).values('name','av')
# print() # F比较就是把两个字段直接比较 而以前用的是把字段的值求出来再比较
from django.db.models import F,Q #这个是查询你的评论数大于你的 阅读数加100的书籍
# ret = Book.objects.filter(comment_count__gt = F('read_count')+100)
# print(ret)
Q查询:
#Q 需要用到 这三个判读条件 & | ~
# & 是and的意思 |是或的意思 ~是非的意思
#这个是查找你的价格大于50 或者阅读数不是大于30的 并且出版时间的年份是2017年的
ret = Book.objects.filter(Q(Q(price__gt = 50)|~Q(read_count__gt=30)&Q(pub_date__year = '')))
print(ret) return HttpResponse('')
基于双下划线的跨表查询 (join查询)的更多相关文章
- python 全栈开发,Day74(基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询)
昨日内容回顾 # 一对多的添加方式1(推荐) # book=Book.objects.create(title="水浒传",price=100,pub_date="164 ...
- {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询
Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...
- (转)python 全栈开发,Day74(基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询)
昨日内容回顾 # 一对多的添加方式1(推荐) # book=Book.objects.create(title="水浒传",price=100,pub_date="164 ...
- (20)模型层 -ORM之msql 基于双下划线的跨表查询(一对一,一对多,多对多)
基于对象的跨表查询是子查询 基于双下划线的查询是连表查询 PS:基于双下划线的跨表查询 正向按字段,反向按表名小写 一对一 需求:查询lqz这个人的地址# 正向查询ret = models.Autho ...
- Django基础(5) ----基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询
一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...
- Django Mysql数据库-基于双下划线的跨表查询
一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...
- django orm 基于双下划线的跨表查询
一..基于双下划线的跨表查询(join实现) key:正向查询按字段,反向查询按表明小写 1.一对多跨表查询 查询在跨表中可以有两种方式,正向查询就是关键字段在你要搜索的表,没有关键字段就是反向查询 ...
- Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询
Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...
- Django学习——图书相关表关系建立、基于双下划线的跨表查询、聚合查询、分组查询、F查询、Q查询、admin的使用、使用脚本调用Django、Django查看源生sql
0 图书相关表关系建立 1.5个表 2.书籍表,作者表,作者详情表(垂直分表),出版社表,书籍和作者表(多对多关系) 一对一 多对多 本质都是一对多 外键关系 3.一对一的关系,关联字段可以写在任意一 ...
- $Django 多对多-自定义第三张表 基于双下划线的跨表查询(补充)
自定义第三张表的好处:可以定义多个字段, 缺点:查询不方便(有方法解决) 1.第三张表设置外键,联合唯一(查询不方便) class Books(models.Model): name=models.C ...
随机推荐
- redis 数据类型 Hash
Redis 数据类型Hash:hash数据类型存储的数据和mysql数据库中存储的一条记录很类似. hash的一些操作: 比如数据库是user表,有id,name,age ,sex,可以建立与之对应的 ...
- Oracle 创建表空间和用户
创建用户: 建立表空间和用户的步骤: 用户 建立:create user 用户名 identified by "密码"; 授权:grant create session to 用户 ...
- ognl,jstl,struts2标签中符号#,$,%的用法
STRUTS2标签操作Map <s:iterator value="sundayMap"> <td colspan="7" ...
- WordNet::Similarity的安装和使用
简介 WordNet::Similarity是一个Perl实现的软件包,可以用来计算两个概念(或者word sense)之间的语义相似度,它提供了六种计算相似度和三种计算概念之间关联度的方法,所有的这 ...
- 将一个表的数据导入到另一个表的sql
ALTER PROCEDURE [dbo].[usp_ea_Copy] ( @eaId int, @createdBy varchar(), @newEaId int output ) AS decl ...
- Rsyslog+ELK日志分析系统
转自:https://www.cnblogs.com/itworks/p/7272740.html Rsyslog+ELK日志分析系统搭建总结1.0(测试环境) 因为工作需求,最近在搭建日志分析系统, ...
- MySQL (一)(未完成)
并发控制 读写锁 读锁: 共享锁 写锁: 排它锁 颗粒度 表锁,MySQL中开销最小的锁 行锁,MySQL中开销最大的锁 事务 ACID特性 原子性(Automatic) 隔离性(Isolation) ...
- JMM和底层实现原理
- 深入分析ReentrantLock公平锁和非公平锁的区别 (转)
在ReentrantLock中包含了公平锁和非公平锁两种锁,通过查看源码可以看到这两种锁都是继承自Sync,而Sync又继承自AbstractQueuedSynchronizer,而AbstractQ ...
- Java 并发:线程中断-interrupt
一直以为执行了interrupt方法就可以让线程结束,并抛出InterruptedException. 今天看了Java并发编程实战的第七章发现并不是这么回事,在这章的开头就提到 要使任务和线程能安全 ...