在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. 阿里云服务器外网IP无法访问网站

    1.添加IIS时添加了127.0.0.1的IP监听导致无法访问外网IP 添加IP监听:netsh http add iplisten 127.0.0.1显示IP监听:netsh http show i ...

  2. 5.Topic与Partition

  3. linux学习(十一)linux安装nginx

    一.前言 由于本地练手的小demo用的是vue+spring boot来玩的,所以部署的时候想着用Nginx来实现反向代理[即请求转发,解决前后端分离的跨域请求问题],既然要用,那么首先得在服务器上面 ...

  4. 论文阅读 A SIMPLE BUT TOUGH-TO-BEAT BASELINE FOR SEN- TENCE EMBEDDINGS

    这篇论文提出了SIF sentence embedding方法, 作者提供的代码在Github. 引入 作为一种无监督计算句子之间相似度的方法, sif sentence embedding使用预训练 ...

  5. 简单两步使用css控制div下导航栏ul居中显示

    第一步:父层设置文本居中属性 ul{ text-align:center; } 第二步:li设置内联样式 li{ display:inline; } PS 只需以上两步就可以实现导航栏居中显示了,但为 ...

  6. 为cmd中的命令添加别名,以解决java:错误: 编码 GBK 的不可映射字符 (0xAF)

    使用sublineText3编写了java代码,通过cmd javac编译 提示 错误:编码GBK的不可映射字符 解决方法 使用javac -encoding UTF-8 Person.java 结果 ...

  7. matlab中imfinfo 有关图形文件的信息

    来源:https://ww2.mathworks.cn/help/matlab/ref/imfinfo.html?searchHighlight=imfinfo&s_tid=doc_srcht ...

  8. MATLAB中exist函数的用法

    exist:exist主要有两种形式,一个参数和两个参数的,作用都是用于确定某值是否存在:1. b = exist( a)      若 a 存在,则 b = 1: 否则 b = 0:2. b = e ...

  9. str常用操作方法

    1. 索引(即下标) s = 'ABCDEFGHIJKLMN' s1 = s[0] print('s[0] = ' + s1) #s[0] = A print('s[3] = '+ s[3]) #s[ ...

  10. ABP vnext模块化架构的最佳实践的实现

    在上一篇文章<手把手教你用Abp vnext构建API接口服务>中,我们用ABP vnext实现了WebAPI接口服务,但是并非ABP模块化架构的最佳实践.我本身也在学习ABP,我认为AB ...