当前位置: 首页 > news >正文

Django中QuerySet 的惰性加载

在 Django 中,QuerySet 的惰性加载(Lazy Evaluation) 是指:当你创建一个 QuerySet 时,Django 并不会立即执行数据库查询,而是等到你真正需要使用查询结果时(比如遍历、切片、转换为列表等),才会去数据库中执行对应的 SQL 查询。


📌 惰性加载的核心思想

“不到最后一刻,绝不执行数据库操作。”

这样做的好处包括:

  • 提高性能:避免不必要的数据库访问。
  • 支持链式操作:可以多次对 QuerySet 进行过滤、排序等操作,最终只生成一条优化后的 SQL。
  • 减少资源消耗:只有在真正需要数据时才加载。

✅ 示例说明

# 1. 创建 QuerySet —— 不会立即查数据库
queryset = User.objects.filter(is_active=True)# 2. 链式操作 —— 依然不会查数据库
queryset = queryset.order_by('username')# 3. 只有在以下情况之一发生时,才会真正执行 SQL:
print(list(queryset))        # 转为 list
for user in queryset:        # 遍历print(user.username)
len(queryset)                # 获取长度(注意:这会执行 SELECT COUNT(*) 或全查)
bool(queryset)               # 判断是否为空
repr(queryset)               # 在 Django shell 中打印也会触发

⚠️ 注意事项

  • 每次使用未缓存的 QuerySet 都可能触发一次新查询。例如:

    users = User.objects.all()
    print([u.name for u in users])  # 查询 1
    print([u.email for u in users]) # 查询 2(如果未缓存)

    但如果你将 QuerySet 转为 list,就只会查一次:

    users = list(User.objects.all())  # 立即执行查询并缓存结果
  • 某些操作会强制求值(e.g., list(), len(), exists() 等),而有些操作仍返回新的惰性 QuerySet(e.g., filter(), exclude(), order_by())。


🔍 如何验证是否执行了查询?

你可以使用 Django 的 connection.queries(需开启 DEBUG=True)或使用 django.db.connection 来查看实际执行的 SQL:

from django.db import connectionqs = User.objects.filter(is_active=True)
print(len(connection.queries))  # 0 —— 尚未查询list(qs)
print(len(connection.queries))  # 1 —— 已执行查询

总结

行为是否触发数据库查询
User.objects.all()❌ 否
.filter().order_by()❌ 否
list(qs)for obj in qs✅ 是
qs.exists()qs.count()✅ 是(但只执行轻量查询)

Django 的 QuerySet 惰性加载机制是其高效 ORM 的核心特性之一,合理利用可以显著优化 Web 应用性能。

http://www.dtcms.com/a/597070.html

相关文章:

  • 会议平台网站建设汇通网做期货的网站做期货的网站
  • 【计网】基于三层交换机和 RIP 协议的局域网组建
  • 【系统架构设计】用例技术:需求分析的实用工具
  • 网站设计需要什么软件python基础教程ppt
  • ffmpeg7.1.2-官方示例demo预览
  • 自己怎么优化我网站关键词潍坊尚呈网站建设公司
  • 数据科学每日总结--Day16--数据库
  • 从“高门槛”到“零门槛”:ArcGIS 和 GISBox如何破解中小用户GIS工具使用难题?
  • 152.当数据写入速度远大于读取时速度时控制信息的处理方法
  • 【MQ】集群部署和可靠性攻略
  • 数字上变频DUC与数字下变频DDC的介绍
  • 网站换代理wordpress首页链接哪里设置
  • 【Git】请帮忙解释一下“git reset”
  • Linux 二进制兼容性的糟糕现状(以及如何解决)
  • Next.js第三章(App Router)
  • 长芯微LPS1032完全P2P替代LM3880,LPS1032系列产品是简单的电源序列器,提供多通道电源的加电和断电顺序控制。
  • 百度提交网站收录建筑网址大全
  • TensorFlow深度学习实战——胶囊网络
  • [Linux]学习笔记系列 -- [kernel]kallsyms
  • 手机代理企业网站wordpress农业站模板
  • 门户网站开发的意义ppt 做的最好的网站有哪些
  • 龙岗AI搜索优化亲测效果分享
  • 【多源 BFS】1. 01 矩阵(medium)
  • 物联网工控一体机操作系统选型:安卓、Ubuntu、Debian 场景化决策指南
  • 【代码审计】RuoYi-4.2 五处安全问题分析
  • 如何制作自己的网站并且插口代码wordpress .htaccess 伪静态
  • 【openGauss】谈一谈openGauss对Oracle中lob类型的兼容情况
  • 【自然语言处理】WordNet与知网:支撑自然语言理解的词汇知识库双璧
  • 怎么自己弄一个网站编程课程收费标准
  • Vue 项目实战《尚医通》,登录组件获取验证码,笔记25