在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. 循环删除list的方法

    错误的方法: 正确的方法:

  2. [剑指Offer]55-题目一:二叉树的深度 题目二:平衡二叉树

    题目一 题目 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 题解 递归. 代码 class TreeNode { int v ...

  3. Magicodes.IE 2.3重磅发布——.NET Core开源导入导出库

    在2.3这一版本的更新中,我们迎来了众多的使用者.贡献者,在这个里程碑中我们也添加并修复了一些功能.对于新特点的功能我将在下面进行详细的描述,当然也欢迎更多的人可以加入进来,再或者也很期待大家来提is ...

  4. Java程序员必备基础:JDK 5-15都有哪些经典新特性

    前言 JDK 15发布啦~ 我们一起回顾JDK 5-15 的新特性吧,大家一起学习哈~ 本文已经收录到github ❝ https://github.com/whx123/JavaHome ❞ 「公众 ...

  5. AOP参数校验

      1.切面依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId&g ...

  6. 深入理解HBase

    深入理解HBase: https://www.jianshu.com/p/b23800d9b227

  7. PHP代码审计01之in_array()函数缺陷

    前言 从今天起,结合红日安全写的文章,开始学习代码审计,题目均来自PHP SECURITY CALENDAR 2017,讲完这个题目,会再用一道有相同问题的CTF题来进行巩固.下面开始分析. 漏洞分析 ...

  8. Processing 高效控制管理图形方法(一)

    之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/62456299

  9. 国产化之路-安装WEB服务器

    专题目录 国产化之路-统信UOS操作系统安装 国产化之路-国产操作系统安装.net core 3.1 sdk 国产化之路-安装WEB服务器 国产化之路-安装达梦DM8数据库 国产化之路-统信UOS + ...

  10. RabbitMQ小记(三)

    1.RabbitMQ中mandatory和immediate以及备份交换机 (1)mandatory为true时,若交换机无法根据自身类型和路由键找到符合条件的对列,那么RabbitMQ会回调Basi ...