Django 查询结果集(QuerySet)终极 5 分钟速记

举报
周杰伦本人 发表于 2025/08/31 20:25:39 2025/08/31
【摘要】 Django 查询结果集(QuerySet)终极 5 分钟速记一、QuerySet 是什么?一句话:ORM 把数据库行“打包”成可链式操作的 Python 列表对象,但它比 list 更聪明。QuerySet 是 Django ORM 返回的“延迟求值”列表容器。它长得像 list,却自带 SQL 生成器:只有真正需要数据时,才会把条件翻译成 SELECT 语句发往数据库。因此,你可以把它...

Django 查询结果集(QuerySet)终极 5 分钟速记

一、QuerySet 是什么?
一句话:ORM 把数据库行“打包”成可链式操作的 Python 列表对象,但它比 list 更聪明。

QuerySet 是 Django ORM 返回的“延迟求值”列表容器。它长得像 list,却自带 SQL 生成器:只有真正需要数据时,才会把条件翻译成 SELECT 语句发往数据库。因此,你可以把它想象成“会说话的 SQL 草稿纸”。

二、两大特性(这个面试常问)

  1. 惰性(Lazy)
    代码只定义查询条件,不立即发 SQL;真正遍历、切片、打印时才执行。
qs = Book.objects.all()          # 此时 0SQL
list(qs)                         # 第一次真正查库
  • 好处:随意链式调用,不担心性能浪费。
  1. 缓存(Cache)
    同一个 QuerySet 第一次遍历后,结果会常驻内存,反复用不会重复查硬盘。
qs = Book.objects.all()
for b in qs: pass                # 第一次,SQL → 内存
for b in qs: pass                # 第二次,直接用内存
  • 注意:如果重新赋值 qs = Book.objects.all(),缓存失效。

三、常见操作速查表

目的 写法 说明
取第一条 qs[0]qs.first() 下标从 0 开始
切片分页 qs[0:10] 相当于 LIMIT 10
总条数 qs.count() 用 SQL COUNT,不拉全部数据
转成列表 list(qs) 触发真正的查询
去重 qs.distinct() 同 SQL DISTINCT

四、分页 2 条路

  1. 手动切片(适合小量数据)
page = 2
per_page = 5
books = Book.objects.all()[(page-1)*per_page : page*per_page]
  1. Paginator 类(官方推荐,项目必用)
from django.core.paginator import Paginator
paginator = Paginator(Book.objects.all(), 5)
page2 = paginator.page(2)

把“全部图书”切成每页 5 条,然后取第 2 页的数据。

逐段拆解

  1. Book.objects.all():拿到所有图书(暂时不真正查库,惰性)。

  2. Paginator(..., 5):告诉 Django “每页最多 5 条”。

  3. page(2)
    • 自动计算 OFFSET & LIMIT → 生成 SELECT … LIMIT 5 OFFSET 5
    • 返回一个 Page 对象,里面装着第 2 页的 5 本书,以及是否有上一页/下一页等信息。

后续可直接在模板里使用:

for book in page2:          # 遍历第 2 页的书
    print(book.name)

if page2.has_next():        # 判断是否存在第 3...

这也是我们在项目中经常用的

五、30 秒口诀

不遍历不查库,切片就能 LIMIT,Paginator 是项目标配。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。