• Django ORM Queryset 的缓存机制, 惰性查询简述


    在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'
    
  • 相关阅读:
    android 发送短信 怎样做到一条一条的发送,仅仅有在上一条发送成功之后才发送下一条短信
    qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
    C小加 之 随机数
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    WIZnet推出串口转以太网模块WIZ550S2E
    java里,当long与上了int
    几个常见字符串处理函数的实现原理
    Android平台调用Web Service:演示样例
    怎样学好游戏编程
    void及void指针含义的深刻解析
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/13841886.html
Copyright © 2020-2023  润新知