#下面两种是基于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. Kali安装zmap简单介绍

    zmap是一个非常方便的扫描器,跟nmap和masscan一样,不过区别在于zmap他快,号称是一小时扫遍整个互联网.主要使用方式是TCP SYN scan.TCP connectscan.UDP s ...

  2. C# 切分图片

    public void Slice() { // 图片路径 var file = "F;/aaa.png"; // 水平切分 ; // 纵向切分 ; ; i < horizo ...

  3. redis key命令

    key命令主要用于管理redis中的key del key //删除key, 不存在的key会忽略 dump key //序列化key,不存在的key返回nil exists key //判断key是 ...

  4. 树的子结构(JAVA)

    树的子结构 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) public boolean HasSubtree(TreeNode root1, T ...

  5. C++ 自定义时间

      今天精神状态不好,和公司的领导请了假.为了抵抗我的痛苦,我在床上打坐冥想,从早上九点到下午三点二十六.嗯,感觉好多了.这种温和的暴力果然有效.   之后吃了点东西,然后无聊的我就在想,明天的工作该 ...

  6. linux路由

    https://www.cnblogs.com/luckyall/p/6418965.html https://www.cnblogs.com/dapaitou2006/p/6564622.html一 ...

  7. 给jumpserver双机配置glusterfs共享复制卷

    为什么要使用glusterfs呢. 本身Haproxy+Keepalived对jumpserver进行了负载均衡和反向代理.但是真实的视频只会存储在一个节点上 否则播放视频的时候会出现找不到的情况 为 ...

  8. rsync命令简单用法介绍

    rsync有两种常用的认证方式,一种为rsync-daemon方式,另外一种则是ssh.在一些场合,使用rsync-daemon方式会比较缺乏灵活性,ssh方式则成为首选.但是今天实际操作的时候发现当 ...

  9. docker nginx letsencrypt

    https越来越流行了,但免费的证书一般是一年有效期.一般是够用了,但懒人都想一劳永逸, 有个免费证书颁发机构是letsencrypt.它是开源,并且完全免费的,它颁发的证书已经被几乎所有的浏览器所认 ...

  10. css格式

    <head> <style>body {color:#000000;font-weight:normal;} .c1{ color: #fff; background-colo ...