---------->惰性机制:

所谓惰性机制: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集合对象的特性相关推荐

  1. html显示queryset,Django用queryset将对象从视图返回到HTML?

    我试图用HTML显示Django中查询集的一些信息.但我不知道最好的办法.在 我的想法是,当我打开网页,这显示了用户的名字和与之相关的比赛.用户可以在Django的管理中创建竞争.在 我的网址是.在u ...

  2. django中queryset的两大特性

    roles = RoleInfo.objects.all() 一.查询集的惰性执行 创建查询集的时候,是不会访问数据库的,直到真正的调用数据的时候,才会访问数据库,所以 roles = RoleInf ...

  3. Django ORM 单表操作

    默认使用sqllite数据库 创建表 # models.py form django.db import models class Book(models.Model): # 表名book,djang ...

  4. Django ORM之QuerySet

    阅读目录 Django ORM用到三个类:Manager.QuerySet.Model.Manager定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类 ...

  5. Django(22)-ORM中F对象和Q对象

    Django(1)-简介 Django(2)-创建项目及默认项目目录结构介绍 Django(3)-配置文件详解 Django(4)-URL和视图 Django(5)-路由配置实例 Django(6)- ...

  6. Django OMR QuerySet的特性/存在意义

    QuerySet存在的意义主要在惰性机制和缓存两点 ---------->惰性机制: 所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个Quer ...

  7. Django ORM – 多表实例:Django模型Model的定义+模型间关系

    Django 对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django 为这些数据库提供了统一的调用API. 我们可以根据自己业务需求选择不同的 ...

  8. Django ORM – 多表实例

    文章目录 Django ORM – 多表实例 创建模型 实例 表结构 插入数据 ORM - 添加数据 一对多(外键 ForeignKey) app01/views.py 文件代码: app01/vie ...

  9. Django ORM操作

    Django ORM操作 一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果<2> get(**kwargs): 返回与所给筛选条 ...

最新文章

  1. Java Spring MVC项目搭建(三)——“Hello World”
  2. Asp.NetCore MVC Web 应用
  3. 如何通过一个SDK轻松搞定人脸识别,拯救初入职场的程序猿
  4. Altium AD20更改原理图背景颜色
  5. xposed获取context 的方法
  6. SpringMVC中实现文件上传
  7. vuex中store存储store.commit和store.dispatch的区别及用法
  8. 网络与多媒体机基础知识易错知识点汇总
  9. 解决打印机后台程序服务没有运行
  10. ASCII码为0x01,0x02作为分隔符(这两个字符是键盘无法输入的)
  11. 【Windows安装WSL】WSL中安装Ubuntu发行版,提示占位程序接收到错误数据
  12. 电路交换、报文交换、分组交换三种数据交换方式的特点、优点、应用场景以及技术对比分析
  13. DOS中使用扩展内存与XMS操作库设计
  14. 国内外MCU厂商及产品线最全盘点
  15. 电脑流量监控软件监控局域网员工电脑流量使用情况
  16. 工业设备远程监控与维护系统
  17. 2021年哈工程计算机考研经验分享(从初试到录取)
  18. WinDebug使用
  19. 考研英语一小作文原创高分范文分享
  20. 【实践经验】PPT导出SVG格式通过Inkscape转化为pdf

热门文章

  1. 网易2017春招笔试真题编程题集合
  2. 单链表的基础操作练习
  3. 多线程实战(二)线程同步
  4. 字符串参数传递与返回值(转)
  5. CodeFirst 表之间的关联
  6. Windows Phone 保存录音
  7. 1过程流程图 3 apqp_干货 | APQP过程流程图及最新版全套表格汇总,收藏备用!
  8. Mybatis Plus配置以及单表操作
  9. 过去几年接触了很多小公司小品牌
  10. 教培机构实际运营过程中会遇到的问题