在Django的ORM中 必须注意由于QuerySet的 cache导致的数据获取不正确的问题

在哪些情况下不会出发QuerySet缓存?

隐式存储QuerySet(查询语句没有显示赋值给变量而直接进行遍历或截取)

>>> from project.models import ProjectModel
>>>
>>> print([project_instance.name for project_instance in ProjectModel.objects.all()])
['first-test', 'test百度', 'project002']
>>> ProjectModel.objects.filter(name="project002").update(name="project003")
1
>>> print([project_instance.name for project_instance in ProjectModel.objects.all()])
['first-test', 'test百度', 'project003']

而显示的存储QuerSet 并且经过完整遍历才会触发缓存

完整遍历的情况

>>> projects_queryset = ProjectModel.objects.all()
>>> print([project_instance for project_instance in projects_queryset]) # 完整遍历
[<ProjectModel: first-test>, <ProjectModel: test百度>, <ProjectModel: project007>]
>>> ProjectModel.objects.filter(name="project007").update(name="project008")
1
>>> projects_queryset[1:3]
[<ProjectModel: test百度>, <ProjectModel: project007>] # project007还是缓存的老数据

不遍历的情况

>>> projects_queryset = ProjectModel.objects.all()
>>> projects_queryset
<QuerySet [<ProjectModel: first-test>, <ProjectModel: test百度>, <ProjectModel: project008>]>
>>> ProjectModel.objects.filter(name="project008").update(name="project009")
1
>>> projects_queryset[1:3]
<QuerySet [<ProjectModel: test百度>, <ProjectModel: project009>]> # 没拿缓存 project009

还有一种场景 也是需要注意的:

获取到单个QuerySet对象后 通过objects update方法修改了部分字段值,此时的QuerySet还是缓存数据

>>> projects_obj = ProjectModel.objects.filter(name="project0011").first()
>>> projects_obj.name
'project0011'
>>> ProjectModel.objects.filter(name="project0011").update(name="project0012")
1
>>> projects_obj.name
'project0011'

有两种方法可以解决这个问题

  1. 使用save修改
>>> projects_obj = ProjectModel.objects.filter(name="project0012").first()
>>> projects_obj.name
'project0012'
>>> projects_obj.name = "project0013"
>>> projects_obj.save()
>>> projects_obj.name
'project0013'
  1. 使用refresh_from_db()
>>> projects_obj = ProjectModel.objects.filter(name="project0013").first()
>>> projects_obj.name
'project0013'
>>> ProjectModel.objects.filter(name="project0013").update(name="project0014")
1
>>> projects_obj.refresh_from_db()
>>> projects_obj.name
'project0014'

Django ORM Queryset 的缓存机制, 惰性查询简述的更多相关文章

  1. Django ORM queryset object 解释(子查询和join连表查询的结果)

    #下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) --- ...

  2. Python - Django - ORM QuerySet 方法补充

    models.py: from django.db import models class Employee2(models.Model): name = models.CharField(max_l ...

  3. Django - ORM - 进阶

    一.多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是 ...

  4. Django ORM基础篇【转载】

    ORM( Object relational mapping 对象关系映射)D:把面向对象中的类和数据库表一一对应起来,在django项目与数据库之间起着桥梁的                     ...

  5. Django ORM 高性能查询优化

    一.QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. >>> Entry.objects.all( ...

  6. Django ORM操作及进阶

    一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 ...

  7. 详解ASP.NET缓存机制

    文中对ASP.NET的缓存机制进行了简述,ASP.NET中的缓存极大的简化了开发人员的使用,如果使用得当,程序性能会有客观的提升.缓存是在内存存储数据的一项技术,也是ASP.NET中提供的重要特性之一 ...

  8. redis的介绍与操作及Django中使用redis缓存

    redis VS mysql的区别 """ redis: 内存数据库(读写快).非关系型(操作数据方便) mysql: 硬盘数据库(数据持久化).关系型(操作数据间关系) ...

  9. Django orm的惰性机制

    Django惰性机制 所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用Quer ...

随机推荐

  1. ajax之---上传图片和预览

    views.py def upload_img(request): nid=str(uuid.uuid4()) ret={'status':True,'data':None,'message':Non ...

  2. 实用js方法DataUrl转为File、url转base64

    声明:仅为方便自己所需,也希望能方便他人,如有侵权,联系删除. 1,DataUrl转为File /** * DataUrl转为File * @param {String} dataUrl - data ...

  3. [LeetCode]33. 搜索旋转排序数组(二分)

    题目 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中存在这个目 ...

  4. JVM运行时数据区--方法区

    运行时数据区结构图(温习): 堆.栈.方法区的交互关系 方法区的理解 方法区(Method Area)与Java堆一样,是各个线程共享的内存区域 方法区在JVM启动时就会被创建,并且它的实际的物理内存 ...

  5. apisix docker镜像构建及插件化开发

    高能劝退:lua开发,适合小白看!!! 前段时间有个项目,用的java程序做网关,压测tps只有1k多点,惨不忍睹. 后来公司有个大佬改用apisix做网关,tps飙升到1w多. 于是对神奇的apis ...

  6. python中RGB色彩

    turtle.colormode(mode)来改变色彩数值的使用 如果在修改颜色时写turtle.colormode(1.0) ,就需要使用RGB小数模式来去改变颜色 如果在修改颜色时写turtle. ...

  7. TX-LCN分布式事务框架使用

    官方文档相关: GitHub地址:https://github.com/codingapi/tx-lcn 官方文档:https://www.codingapi.com/docs/txlcn-prefa ...

  8. Docker:一、开始部署第一个Asp.net应用

    工具: docker desktop :一个使用Docker的IDE工具,可以理解为SourceTree,也是使用git的一个桌面化工具: kitematic :配合desctop,用来管理本地的镜像 ...

  9. svn的使用学习

    一:安装 1.svn安装包,语言包下载 地址:https://pan.baidu.com/s/1PFM7ya_hNJM-v979KgCpgA 提取码:mpxq 2.运行下载的TortoiseSVN程序 ...

  10. powerDesiger的学习

    一:简介 二:建立物理模型(正向工程) 1.创建 (1) file->new Model创建需要的物理模型,设置使用的数据库. 2.物理模型的数据库设计 (1)一个物理模型中可以有好几张数据库表 ...