Django ORM queryset object 解释(子查询和join连表查询的结果)
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询
books = models.UserInfo.objects.all()
print(type(books)) ---> <class 'django.db.models.query.QuerySet'> 查询出来是一个对象QuerySey
取值 print(books.values())
books = models.UserInfo.objects.filter()
print(type(books)) ---> <class 'django.db.models.query.QuerySet'> 查询出来一个QureySet
取值 print(books.values())
总结:books查询来了结果是queryset,然后在这个基础上面查询作者的名字,也就是跨表查询,这时候就需要用values去获取另外一个表的数据.
怎么获取呢? 就通过books.values("user__name") user是UserInfo表字段的名称 __代表双下划线
#基于对象的查询 也就是说SQL中用的子查询,就是slecte 里面套了slecte查询方式
books = models.UserInfo.objects.first()
print(type(books)) ---> <class 'app.models.UserInfo'> 查询出来是一个对象
取值 print(books.password)
总结:什么是基于对象? 就是说books对象已经拿到了,相当于就是表中的name这个对象已经查询到了,然后对象点属性取值就可以了
可以用点的方式获取数据 books.name 或者 book.age 等
############基于对象查询(子查询)##########
#
# 一对多
# 正向查询按字段(publish) book -----------------> publish
# 反向查询表名小写_set.all() book <---------------- publish
#
'''
class Author(models.Model):
作者表
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField() # 与AuthorDetail建立一对一的关系
authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE) class AuthorDetail(models.Model):
'作者详情
nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64) class Book(models.Model):
书籍表
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
price=models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author',) class Publish(models.Model):
出版社表
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField()
''' # 查询python这本书籍的出版社的邮箱
'''
py = models.Book.objects.filter(title="python").first()
print(py) # 加first 获取到是一 Book object (1) 直接点获取数据 py = models.Book.objects.filter(title="python")
print(py) #不加first 获取到是一个 <QuerySet [<Book: Book object (1)>]> 需要for获取数据
for i in py:
print(i.publish.email) py = models.Book.objects.filter(title="python").first()
print(py.publish.email)
''' #反向查询 苹果出版社出版的书籍名称
'''
pu = models.Publish.objects.filter(name="苹果出版社").first() ##获取第一个对象,然后点就可以了
print(pu.book_set.all()) #出版社出了很多书就需要用到all
for i in pu.book_set.all():
print(i.title)
''' #一对一的查询 , 查询作者地址是纽约的
'''
ret = models.AuthorDetail.objects.filter(addr="纽约").first() #获取第一个对象,然后点就可以了
print(ret.author.name) ret = models.AuthorDetail.objects.filter(addr="纽约") #设计2个纽约地址,所以要用for
for i in ret:
print(i.author.name)
''' ################基于queryset和__查询(join查询)############################ # 正向查询:按字段 反向查询:表名小写 # 正向查询 查询python这本书的出版社邮箱
'''
ret = models.Book.objects.filter(title="python").values("publish__email").first() #values 显示什么字段, 需要找publish里面的有个email字段,用到__(publish__email)
print(ret)
'''
'''
values("publish__email"). == select publish.email from SQL:
select * from Book
left jion Publish
ON (Book.publish=Publish.nid)
where Book.title="python"
解:
select publish.email from Book
Book left jion Publish 查询book和出版社应该跨那张表
ON (Book.publish=Publish.nid) 条件是什么? Book.publish_id(Book表的关联ID) 等于 Publish.nid(出版社关联ID)
where Book.title="python" 查询python这本书, 为什么要在title 前面加Book 怕跨表有重复的
''' #反向查询 查询苹果出版社的书籍名称 按表名__字段名
'''
方式1
ret = models.Publish.objects.filter(name="苹果出版社").values("book__title")
print(ret) 方式2
ret = models.Book.objects.filter(publish__name="苹果出版社").values("title") #查询book表过滤出版社是苹果出版社的 拿title值
print(ret)
''' #查询手机号以111111111开头的作者出版过的书籍名称以及书籍对应的出版社名称 telephone="111111111" '''
ret = models.Book.objects.filter(authors__authorDetail__telephone__startswith="111").values('title',"publish__name")
print(ret)
''' '''
首先要弄清楚各个表之间的关系
Author(作者) 一对一 到 AuthorDetail(作者详情)
Book(书籍) 一对多 到 publish(出版社)
Book(书籍) 多对多 到 Author(作者)
'''
# 查询手机号以222222开头的作者出版过的书籍名称以及书籍对应的出版社名称 telephone="111111111"
'''
ret = models.AuthorDetail.objects.filter(telephone__startswith="22222").values("addr","author__name","author__book__title","author__book__publish__name")
#1 telephone__startswith="22222" 首先查询出来作者详情里面的手机号码是22222开头的
#2 values("addr","author__name","author__book__title","author__book__publish__name")
查询以为2222开头的地址,
author__name(找到当前手机号码对应的作者名字, Author(作者)一对一到AuthorDetail(作者详情), 反向查询到name )
author__book__title(Book(书籍)多对多到Author(作者), 反向查询 找到当前手机号码,对应的作者名字,通过作者反向查询作者出过的书名称,必须要通过作者找,直接book__title,不知道要查询什么)
author__book__publish__name(反向查询 通过作者反向查询作者出过的书的出版社名称)
print(ret)
'''
ORM补充:
books = models.UserInfo.objects.all().values('id','name') ---> queryset=[{},{}]
books = models.UserInfo.objects.all().values_list('id','name') ---> queryset=[(),()]
books_s = models.UserInfo.objects.all().only('id','name') ---> queryset=[obj,obj}]
for i in books_s:
print(i.id,i.name,i.age) #上面没取age,这时候获取age能获取到,但是有会重新去查询一次,这样性能降低
books_s = models.UserInfo.objects.all().defer('id','name') ---> queryset=[obj,obj}] 排除id name 不取 #一对多的时候 打印所有的用户已经部门名称:
class dept:
title = ... class User:
name = ....
dep = FK(dept)
#对于一对一字段(OneToOneField)和外键字段(ForeignKey),可以使用select_related 来对QuerySet进行优化,在对QuerySet使用select_related()函数后,Django会获取相应外键对应的对象,从而在之后需要的时候不必再查询数据库了。
ret = models.User.object.all().selected_related('dep') #selected_related
Django ORM queryset object 解释(子查询和join连表查询的结果)的更多相关文章
- Django ORM 操作 必知必会13条 单表查询
ORM 操作 必知必会13条 import os # if __name__ == '__main__': # 当前文件下执行 os.environ.setdefault('DJANGO_SETTIN ...
- MySQL数据库查询操作进阶——多表查询
多表查询 在大部分情况下,我们用到的表都是彼此相关联的,所以我们会有相当大的需求用到跨表的查询,这个时候我们就需要将相关联的表连起来做多表查询. 多表查询分为连表查询和子查询,连表查询即将相关联的表连 ...
- 对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。
对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引. 问题: 大量的left join 怎么优化 select a.id,a.num,b.num,b.pcs,c.num, c. ...
- mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱
mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱 前言:使用 mybatis generator 生成表格对应的pojo.dao.mapper,以及对应的example的 ...
- MySQL简单查询详解-单表查询
MySQL简单查询详解-单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询的执行路径 一条SQL查询语句的执行过程大致如下图所示: 1>.客户端和服务端通过my ...
- Django ORM 一对一,一对多,多对多, 添加,批量插入和查询
模型类 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_ ...
- Python - Django - ORM QuerySet 方法补充
models.py: from django.db import models class Employee2(models.Model): name = models.CharField(max_l ...
- Django ORM 多对多操作 使用聚合函数和分组 F查询与Q查询
创建表 # models.py form django.db import models class Book(models.Model): # 表名book,django会自动使用项目名+我们定义的 ...
- 65、django之模型层(model)--添加、单表查询、修改基础
上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...
随机推荐
- mongoDB创建windows服务启动解决
最近想了解一下关于MongoDB的知识,记得之前电脑上安装的MongoDB也能正常启用,可是这次在使用mongodb,却遇到一下小麻烦啊.mongodb无法启动,小编很苦恼,尝试了各种方法,甚至卸载重 ...
- Spark源码系列:RDD repartition、coalesce 对比
在上一篇文章中 Spark源码系列:DataFrame repartition.coalesce 对比 对DataFrame的repartition.coalesce进行了对比,在这篇文章中,将会对R ...
- delphi Parallel 之 TTask 初试
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- C# Xamarin开发 GenyMotion adb List of devices attached
最近,公司要求要学习Xamarin,说是将来用到PDA上,所以最近对XaMarin开始接触,16年的时候就听说.Net开始着实跨平台,安卓和IOS,但是网上看过很多资料都说Xamarin比较坑,一般的 ...
- 双网卡单IP实现网卡冗余与负载均衡
WINDOWS下: 所谓双网卡,就是通过软件将双网卡绑定为一个IP地址,这个技术对于许多朋友来说并不陌生,许多高档服务器网卡(例如intel8255x系列.3COM服务器网卡等)都具有多网卡绑定功能, ...
- nginx1.14.0日志打印
nginx日志打印 http属性log_format来设置日志格式 ,参考 https://www.jb51.net/article/52573.htm <nginx日志配置指令详解> ...
- ABBYY FineReader 14OCR解锁
ABBYY FineReader 14是2017年新推的文字处理编辑软件,能够将图像扫描转换成文档处理.不论是在使用群体方面还是功能特性方面都是极好的. •确保扫描仪正确地连接到电脑,并将其打开.查阅 ...
- Tomcat中acceptCount,maxConnections、maxThreads的含义及关系
个人对tomcat连接器3个属性maxConnections.maxThreads.acceptCount的理解: 先摘取官网对这3个属性的描述: acceptCount The maximum qu ...
- MySQL 错误集-汇总
Q&A: MySQl报错之@@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ON 导入的时候加入-f参数即可 原因分 ...
- CentOS 7下Samba服务安装与配置详解
1. Samba简介 Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.SMB(Server Messages Block,信息服务块)是一种在局域网上共 ...