在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. [LeetCode]415. 字符串相加、43. 字符串相乘

    题目 415. 字符串相加 给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和. 题解 维护一个temp表示当前两数相加+上一个进位的和. 每次更新结果的一位. 注意终止条件. 最后将 ...

  2. [算法]体积不小于V的情况下的最小价值(0-1背包)

    题目 0-1背包问题,问要求体积不小于V的情况下的最小价值是多少. 相关 转移方程很容易想,初始化的处理还不够熟练,可能还可以更简明. 使用一维dp数组. 代码 import java.util.Sc ...

  3. js-正则表达式的初步应用(一)

    一.正则表达式是使用单个字符串来描述.匹配一系列符合某个句法规则的字符串搜索模式.注:搜索模式也可用于文本替换 例子1 输出结果  注:(我为了方便在控制台输出,所以结果如下) 例子2 输出结果 上面 ...

  4. 217。数据中是否有重复元素(哈希表/set简法)

    给定一个整数数组,判断是否存在重复元素. 如果任意一值在数组中出现至少两次,函数返回 true .如果数组中每个元素都不相同,则返回 false . 示例 1: 输入: [1,2,3,1] 输出: t ...

  5. matlab外部程序接口-excel

    在excel中使用matlab 内容: 1.Spreadsheet Link 程序 安装与启动 1 打开excle->文件->选项 2.加载项->转到 3.浏览(可用加载宏,本来没有 ...

  6. Excel—使用if(countif())表达式来筛选两个表格中相同的数据

    关注微信公众号:CodingTechWork,一起学习进步. 引言   在线上运维的过程中,遇到一个头疼的事情,有一些合作公司的数据直接从平台上down下来是一个excel,然后发到研发手里去数据库中 ...

  7. Mac新手必看教程——轻松玩转Mac OS

    背景: 大部分用户接触的第一个操作系统大多是windows,本人记得曾经小学的微机课也是以win98为基础学习了一众office软件.随着工作的多样化,单一的windows系统已经无法满足部分需求,而 ...

  8. 【Netty之旅四】你一定看得懂的Netty客户端启动源码分析!

    前言 前面小飞已经讲解了NIO和Netty服务端启动,这一讲是Client的启动过程. 源码系列的文章依旧还是遵循大白话+画图的风格来讲解,本文Netty源码及以后的文章版本都基于:4.1.22.Fi ...

  9. SpringBoot-03-配置之yaml语法学习

    3. SpringBoot配置 3.1 yaml语法学习 配置文件 Springboot使用一个全局的配置文件,配置文件名称固定 spplication.properties 语法结构:key=val ...

  10. 深入研究RocketMQ生产者发送消息的底层原理

    前言 hello,小伙伴们,王子又来和大家研究RocketMQ的原理了,之前的文章RocketMQ生产部署架构如何设计中,我们已经简单的聊过了生产者是如何发送消息给Broker的. 我们简单回顾一下这 ...