在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. python 3 while嵌套

  2. 老男孩教育python全栈第22期Day15笔记

    day15 今日内容大纲 昨日内容回顾作业讲解 装饰器:完美的呈现了开放封闭原则.装饰器的本质:闭包. def wraper(f): def inner(*args, **kwargs): " ...

  3. swift基本数据类型使用

    swift基本数据类型的使用之一: 字符串的使用 swift String的使用 1.字符串的定义 1> 不可变字符串的定义 2> 可变字符串的定义 2.获取字符串的长度 3.字符串的拼接 ...

  4. docker 部署 zabbix

    docker部署zabbix   我相信大家都已经会再物理机上跑zabbix并且监控了,那么有没有想过在docker中跑zabbix?下面咱们来看看如何在docker中搭建zabbix并且监控 部署环 ...

  5. javascript操作多选下拉列表

    闲来无事,把javascript操作多选下拉列表有关的操作知识复习了一遍,代码附上 <%-- Created by IntelliJ IDEA. User: Administrator Date ...

  6. 01 android ndk入门实例之android.mk编译

    前言 1 环境 android studio2.3 , window系统 2 ndk https://dl.google.com/android/repository/android-ndk-r16- ...

  7. chrome浏览器控制台 console不打印信息问题解决办法

    谷歌浏览器控制台不能显示consle打印的东西,我记得之前可以正常打印,代码没问题,可能是你在浏览器中无意间点到了fifter,我们2可以使用最简单粗暴的方法---->恢复默认值. 按下F12, ...

  8. GTA5整合版

    GTA5mod整合版游戏介绍 GTA5mod整合版游戏是一款完美破解的游戏,玩家能够在游戏中享受最爽快的角色动作扮演玩法,在这里你将是一名强大的黑帮分子,在这个都市中,你将体验最真实的黑帮社会玩法.G ...

  9. ACMer不得不会的线段树,究竟是种怎样的数据结构?

    大家好,欢迎阅读周三算法数据结构专题,今天我们来聊聊一个新的数据结构,叫做线段树. 线段树这个数据结构很多人可能会有点蒙,觉得没有听说过,但是它非常非常有名,尤其是在竞赛圈,可以说是竞赛圈的必备技能. ...

  10. Python单向链表的实现

    链表由一系列不必在内存中相连的结构构成,这些对象按线性顺序排序.每个结构含有表元素和指向后继元素的指针.最后一个单元的指针指向NULL.为了方便链表的删除与插入操作,可以为链表添加一个表头. 删除操作 ...