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)--添加、单表查询、修改基础
上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...
随机推荐
- TensorFlow - 在 windows 系统上安装
安装方式: 1.pip (将介绍) 2.Anaconda 我采用的是本地 pip 方式 需提前安装 Python - Python 3.5.x > TF 只支持 Python 3.5.x 版本, ...
- java web(三):ServletContext、session、ServletConfig、request、response对象
上一篇讲了Servlet: 1)什么是Servlet[servlet本身就是一种Java类,这种Java类提供了web形式的方法,只要实现了servlet接口的类,都是一种servlet资源.] 2) ...
- 游戏编程算法与技巧 Game Programming Algorithms and Techniques (Sanjay Madhav 著)
http://gamealgorithms.net 第1章 游戏编程概述 (已看) 第2章 2D图形 (已看) 第3章 游戏中的线性代数 (已看) 第4章 3D图形 (已看) 第5章 游戏输入 (已看 ...
- Vue2.5
1.1 创建第一个Vue实例
- Btrace 拦截时机
Kind.ENTRY 入口,默认值 Kind.RETURN: 返回 Kind.THROW: 异常 Kind.Line: 行 一.返回时拦截 package com.example.monitor_t ...
- rocketmq 4.3.2 解决远程不能消费问题,解决未识别到公网IP问题
1.解决远程不能消费问题 问题描述: nameserver和broker启动后,用tools(命令如下)能发送消息和消费消息,在局域网服务器能发送消息,消费启动后收不到消息通知问题 sh tools. ...
- c# 程序只能运行一次(多次运行只能打开同一个程序)
转自:https://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9/2291420309357 ...
- cocos CCLayer glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);ios11闪退 spine动画
搜索一下方法,找到后替换不同内容: void PolygonBatch::flush () { if (!_verticesCount) return; GL::bindTexture2D(_text ...
- CentOS7.5实践快速部署LAMP+Tomcat成功运行阿里云或者腾讯云
安装一定要按照顺序来 1 先安装JDK+TOMCAT 点击看这里 2 在安装LAMP 点击看这里 3 最关键的就是这里 LAMP+Tomcat整合 我们不用源码编译安装,而是使用yum命令来完成. ...
- @Async异步注解与SpringBoot结合使用
当你在service层需要启动异步线程去执行某些分支任务,又不希望显式使用Thread等线程相关类,只想专注于实现业务逻辑代码开发,可以使用@Async异步注解. 1. 使用@Async 异步注解 C ...