#下面两种是基于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连表查询的结果)的更多相关文章

  1. Django ORM 操作 必知必会13条 单表查询

    ORM 操作 必知必会13条 import os # if __name__ == '__main__': # 当前文件下执行 os.environ.setdefault('DJANGO_SETTIN ...

  2. MySQL数据库查询操作进阶——多表查询

    多表查询 在大部分情况下,我们用到的表都是彼此相关联的,所以我们会有相当大的需求用到跨表的查询,这个时候我们就需要将相关联的表连起来做多表查询. 多表查询分为连表查询和子查询,连表查询即将相关联的表连 ...

  3. 对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引。

    对于大量left join 的表查询,可以在关键的 连接节点字段上创建索引. 问题: 大量的left join 怎么优化 select a.id,a.num,b.num,b.pcs,c.num, c. ...

  4. mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱

    ​ mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱 ​ 前言:使用 mybatis generator 生成表格对应的pojo.dao.mapper,以及对应的example的 ...

  5. MySQL简单查询详解-单表查询

    MySQL简单查询详解-单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询的执行路径 一条SQL查询语句的执行过程大致如下图所示: 1>.客户端和服务端通过my ...

  6. Django ORM 一对一,一对多,多对多, 添加,批量插入和查询

    模型类 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_ ...

  7. Python - Django - ORM QuerySet 方法补充

    models.py: from django.db import models class Employee2(models.Model): name = models.CharField(max_l ...

  8. Django ORM 多对多操作 使用聚合函数和分组 F查询与Q查询

    创建表 # models.py form django.db import models class Book(models.Model): # 表名book,django会自动使用项目名+我们定义的 ...

  9. 65、django之模型层(model)--添加、单表查询、修改基础

    上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...

随机推荐

  1. 疯狂java讲义 第八章课后题

    1.创建一个Set集合,并用Set集合保存用户通过控制台输入的字符串. import java.util.HashSet; import java.util.Scanner; public class ...

  2. Java(常用排序算法)

    冒泡排序 比较相邻的元素.如果第一个比第二个大,就交换他们两个,对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 针对所有的元素重复以上的步骤,除了最 ...

  3. vue 中结合百度地图获取当前城市

    首先需要去百度地图开发者平台申请 ak http://lbsyun.baidu.com/index.php?title=%E9%A6%96%E9%A1%B5 在index.html 中引入script ...

  4. php 合并图片 (将活动背景图片和动态二维码图片合成一张图片)

    <?php //案例一:将活动背景图片和动态二维码图片合成一张图片 //图片一 $path_1 = './background.png'; //图片二 $path_2 = './FU0851_2 ...

  5. Linux 定时任务Crontab的使用

    1.准备好Java程序,导出为Jar文件 如myProject.jar 2.写Shell脚本 startTask.sh echo 'start...' cd  /home/root/yourFolde ...

  6. html5/h5课件如何制作?

    随着flash逐渐被html5取代,很多教育机构都在面临着如何将自己的flash交互课件产品转换到html5版本的问题,最近遇到非常多的客户一上来就问我,flash课件能直接转成Html5课件么?答案 ...

  7. 工控随笔_07_西门子_WinCC利用命令行实现操作log日志

    在WinCC中可以通过报警纪录来实现操作员纪录,这个需要WinCC的消息系统进行组态和配置. 利用消息系统进行实现上诉功能不但复杂而且时间久啦也不方便查询.那么有没有一种简单的方法来 实现操作员纪录呢 ...

  8. TensorFlow的介绍和安装

    TensorFlow概要 由google Brain开源,设计初衷是加速机器学习的研究,2015年11月在GitHub上开源,2016年4月分布式版本,2017年发布了1.0版本,趋于稳定. Tens ...

  9. k2datas 基础编程题,判断字符串是否有重复串

    package String; public class DuplicateString { public static boolean isDup(String s) throws Exceptio ...

  10. iPerf 笔记

    iPerf 笔记 iperf 是一个网络性能测试工具,可以测试最大TCP和UDP带宽质量,具有多种参数和UDP特性,可以报告带宽.延迟抖动和数据包丢失. iperf 可以用来测一些网络设备,比如路由器 ...