Django ORM QuerySet集合对象的特性
---------->惰性机制:
所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。
QuerySet特点:
<1> 可迭代的
<2> 可切片
#objs=models.Book.objects.all()#[obj1,obj2,ob3...]#QuerySet: 可迭代# for obj in objs:#每一obj就是一个行对象# print("obj:",obj)# QuerySet: 可切片# print(objs[1])# print(objs[1:4])# print(objs[::-1])
#objs=models.Book.objects.all()#[obj1,obj2,ob3...]#QuerySet: 可迭代# for obj in objs:#每一obj就是一个行对象# print("obj:",obj)# QuerySet: 可切片# print(objs[1])# print(objs[1:4])# print(objs[::-1])
QuerySet的高效使用:
<1>Django的queryset是惰性的
Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得
到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")
上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,
这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。
<2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.
为了验证这些,需要在settings里加入 LOGGING(验证方式)
obj=models.Book.objects.filter(id=3)
# for i in obj:
# print(i)
# if obj:
# print("ok")
<3>queryset是具有cache的
当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行
(evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,
你不需要重复运行通用的查询。
obj=models.Book.objects.filter(id=3)
# for i in obj:
# print(i)
## models.Book.objects.filter(id=3).update(title="GO")
## obj_new=models.Book.objects.filter(id=3)
# for i in obj:
# print(i) #LOGGING只会打印一次
<4>
简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些
数据!为了避免这个,可以用exists()方法来检查是否有数据:
obj = Book.objects.filter(id=4)
# exists()的检查可以避免数据放入queryset的cache。
if obj.exists():
print("hello world!")
<5>当queryset非常巨大时,cache会成为问题
处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统
进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法
来获取数据,处理完数据就将其丢弃。
objs = Book.objects.all().iterator()
# iterator()可以一次只从数据库获取少量数据,这样可以节省内存
for obj in objs:
print(obj.name)
#BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
for obj in objs:
print(obj.name)
#当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使
#用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询
总结:
queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。
使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能
会造成额外的数据库查询。
<1>Django的queryset是惰性的Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。<2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.为了验证这些,需要在settings里加入 LOGGING(验证方式)obj=models.Book.objects.filter(id=3)# for i in obj:# print(i)# if obj:# print("ok")<3>queryset是具有cache的当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行(evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,你不需要重复运行通用的查询。obj=models.Book.objects.filter(id=3)# for i in obj:# print(i)## models.Book.objects.filter(id=3).update(title="GO")## obj_new=models.Book.objects.filter(id=3)# for i in obj:# print(i) #LOGGING只会打印一次<4>简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些数据!为了避免这个,可以用exists()方法来检查是否有数据:obj = Book.objects.filter(id=4)# exists()的检查可以避免数据放入queryset的cache。if obj.exists():print("hello world!")<5>当queryset非常巨大时,cache会成为问题处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法来获取数据,处理完数据就将其丢弃。objs = Book.objects.all().iterator()# iterator()可以一次只从数据库获取少量数据,这样可以节省内存for obj in objs:print(obj.name)#BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了for obj in objs:print(obj.name)#当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使#用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询总结:queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。 使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能 会造成额外的数据库查询。
转载于:https://www.cnblogs.com/dangrui0725/p/9616274.html
Django ORM QuerySet集合对象的特性相关推荐
- html显示queryset,Django用queryset将对象从视图返回到HTML?
我试图用HTML显示Django中查询集的一些信息.但我不知道最好的办法.在 我的想法是,当我打开网页,这显示了用户的名字和与之相关的比赛.用户可以在Django的管理中创建竞争.在 我的网址是.在u ...
- django中queryset的两大特性
roles = RoleInfo.objects.all() 一.查询集的惰性执行 创建查询集的时候,是不会访问数据库的,直到真正的调用数据的时候,才会访问数据库,所以 roles = RoleInf ...
- Django ORM 单表操作
默认使用sqllite数据库 创建表 # models.py form django.db import models class Book(models.Model): # 表名book,djang ...
- Django ORM之QuerySet
阅读目录 Django ORM用到三个类:Manager.QuerySet.Model.Manager定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类 ...
- Django(22)-ORM中F对象和Q对象
Django(1)-简介 Django(2)-创建项目及默认项目目录结构介绍 Django(3)-配置文件详解 Django(4)-URL和视图 Django(5)-路由配置实例 Django(6)- ...
- Django OMR QuerySet的特性/存在意义
QuerySet存在的意义主要在惰性机制和缓存两点 ---------->惰性机制: 所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个Quer ...
- Django ORM – 多表实例:Django模型Model的定义+模型间关系
Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...
- Django ORM – 多表实例
文章目录 Django ORM – 多表实例 创建模型 实例 表结构 插入数据 ORM - 添加数据 一对多(外键 ForeignKey) app01/views.py 文件代码: app01/vie ...
- Django ORM操作
Django ORM操作 一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果<2> get(**kwargs): 返回与所给筛选条 ...
最新文章
- Java Spring MVC项目搭建(三)——“Hello World”
- Asp.NetCore MVC Web 应用
- 如何通过一个SDK轻松搞定人脸识别,拯救初入职场的程序猿
- Altium AD20更改原理图背景颜色
- xposed获取context 的方法
- SpringMVC中实现文件上传
- vuex中store存储store.commit和store.dispatch的区别及用法
- 网络与多媒体机基础知识易错知识点汇总
- 解决打印机后台程序服务没有运行
- ASCII码为0x01,0x02作为分隔符(这两个字符是键盘无法输入的)
- 【Windows安装WSL】WSL中安装Ubuntu发行版,提示占位程序接收到错误数据
- 电路交换、报文交换、分组交换三种数据交换方式的特点、优点、应用场景以及技术对比分析
- DOS中使用扩展内存与XMS操作库设计
- 国内外MCU厂商及产品线最全盘点
- 电脑流量监控软件监控局域网员工电脑流量使用情况
- 工业设备远程监控与维护系统
- 2021年哈工程计算机考研经验分享(从初试到录取)
- WinDebug使用
- 考研英语一小作文原创高分范文分享
- 【实践经验】PPT导出SVG格式通过Inkscape转化为pdf