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)--添加、单表查询、修改基础
上篇带大家简单做了一下图书表的创建.简单的查看和删除,今天会先简单介绍添加和修改,因为添加和修改与删除一样都很简单,本篇会相对多介绍一点单表查询,大家都知道数据库中查询是最重要的一部分,毕竟无论是修改 ...
随机推荐
- 图片懒加载 echo.js
(function (root, factory) { if (typeof define === 'function' && define.amd) { define(functio ...
- Linux第九节课学习笔记
fdisk可添加.删除.转换分区. 创建主分区:n-p-w:扩展分区:n-e:逻辑分区:n-l. SWAP分区专用格式化命令mkswap,专用挂载命令swapon. 磁盘容量配额中,硬限制必须,软限制 ...
- django 防止xss攻击标记为安全的二种方法
str='<a href="/page?page=1">1</a>' 一,在前端模板语言中实现,只须用到帮助函数safe.如: {{ str|safe }} ...
- MegaCLi命令总结
MegaCli命令总结 MegaCli 版本8.00.29,raid卡为lsi 8888elp,固件11.0.1-0036 1 巡读 一MegaCli -adppr -enblauto -a0 ...
- 通过Nginx使全站页面变灰
摘要:某大神的博客说“在Nginx负载均衡服务器上,利用sub_filter指令在输出的HTML中增加一行:<style type="text/css">html {f ...
- 使用VISIO远程服务器上的ORACLE数据库,反向生成数据库实体关系图
反向即根据已有的数据库,生成ER图,很多工具都可以实现这一过程,如visio,powerdesigner等,下面文章记录一下我使用VISIO生成远程服务器上的一个数据库ER图过程,供以后自己参考. 1 ...
- python解决四舍五入问题
小数问题是计算机编程中大部分语言都会遇到的问题,尤其是在内容中涉及到评分.金额计算等等,本人一般在解决需求中固定小数位的数字计算时,都会先将其放大整10的倍数至整数,然后计算.存储,只有在显示的时候再 ...
- vue插件大全汇总
Vue是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件特别整理了常用的vue插件,来了个大汇总,方便查找使用,便于工作 ...
- 关于使用format()方法格式化字符串,读这一篇就够了!
从Python 2.6开始,又出现了另外一种格式化字符串的方法——format()方法.format()方法是字符串众多方法中的一个,调用这个方法时要使用点操作符(.),该方法返回一个格式化好的字符串 ...
- C#控制台下测试多线程的源码
下边代码是关于C#控制台下测试多线程的的代码,应该是对小伙伴有所用. class Program { static void Main(string[] args) { ThreadStart num ...