You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Django关联对象查询未被缓存?重复查询问题解析

Django QuerySet重复查询问题

我编写了如下单元测试:

def test_cache(self):
    with self.assertNumQueries(1):
        print(database.records.all())
        print(database.records.all())
        print(database.records.all())

测试失败,因为执行了3次查询:

Captured queries were:
1. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
2. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
3. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21

问题原因与解决方法

  • 核心原因:.all()生成新QuerySet实例
    Django的QuerySet是惰性求值的,但.all()方法每次调用都会返回一个全新的QuerySet对象,而非复用之前的查询结果。三次database.records.all()对应三个独立的QuerySet,每次打印时都会触发各自的数据库查询,因此产生了3次SQL请求。

  • 正确的缓存方式:复用同一个QuerySet实例
    要实现缓存效果,需要将QuerySet绑定到变量上,复用同一个实例:

    def test_cache(self):
        with self.assertNumQueries(1):
            records = database.records.all()
            print(records)
            print(records)
            print(records)
    

    第一次打印时,QuerySet被求值并执行数据库查询,结果会被缓存到该实例中;后续再次访问records时,会直接使用缓存的结果,不会触发新的查询。

  • 额外说明:QuerySet的缓存规则
    Django的QuerySet缓存仅针对同一个实例生效。一旦实例被求值(比如迭代、打印、转换为列表),结果就会被缓存。但调用.all()、.filter()、.exclude()等查询方法时,都会生成新的QuerySet实例,这些新实例之间不会共享缓存。

内容的提问来源于stack exchange,提问作者Johnny Metz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:17:07