Django QuerySet 进阶

更多内容,欢迎关注微信公众号:Python知音阁。

什么是QuerySet

QuerySet是Django提供的强大的数据库接口(API)。正是因为通过它,我们可以使用filter, exclude, get等方法进行数据库查询,而不需要使用原始的SQL语言与数据库进行交互。从数据库中查询出来的结果一般是一个集合,这个集合叫就做 queryset。

1. values_list获取元组形式结果

比如我们要获取作者的name和qq这两个字段的信息

authors = Author.objects.values_list(‘name’, ‘qq’)

2. values获取字典形式的结果

比如我们要获取作者的name和qq这两个字段的信息

authors = Author.objects.values(‘name’, ‘qq’)

注意:

  1. values_list 和 values 返回的并不是真正的 列表 或 字典,也是 queryset,他们也是 lazy evaluation 的(惰性评估,通俗地说,就是用的时候才真正的去数据库查)

  2. 如果查询后没有使用,在数据库更新后再使用,你发现得到在是新内容!!!如果想要旧内容保持着,数据库更新后不要变,可以 list 一下

  3. 如果只是遍历这些结果,没有必要 list 它们转成列表(浪费内存,数据量大的时候要更谨慎!!!)

3. annotate 聚合计数,求和,平均数等

3.1计数

计算一下每个作者的文章数

Article.objects.all().values(‘author_id’).annotate(count=Count(‘author’)).values(‘author_id’, ‘count’)

3.2 平均数

求一个作者的所有文章的得分(score)平均值

Article.objects.values(‘author_id’).annotate(avg_score=Avg(‘score’)).values(‘author_id’, ‘avg_score’)

3.3 求和

求一个作者所有文章的总分

Article.objects.values(‘author__name’).annotate(sum_score=Sum(‘score’)).values(‘author__name’, ‘sum_score’)

4. select_related 优化一对一,多对一查询(减少访问数据库的次数)

一篇文章只有一个作者:

articles = Article.objects.all().select_related(‘author’)[:10]

5. prefetch_related优化一对多,多对多查询

和 select_related 功能类似,但是实现不同。select_related 是使用 SQL JOIN 一次性取出相关的内容。prefetch_related 用于 一对多,多对多 的情况,这时 select_related 用不了,因为当前一条有好几条与之相关的内容。

prefetch_related是通过再执行一条额外的SQL语句,然后用 Python 把两次SQL查询的内容关联(joining)到一起

“文章”与“标签”是多对多的关系:

articles = Article.objects.all().prefetch_related(‘tags’)[:10]

6. defer排除不需要的字段

在复杂的情况下,表中可能有些字段内容非常多,取出来转化成 Python 对象会占用大量的资源。

这时候可以用 defer 来排除这些字段,比如我们在文章列表页,只需要文章的标题和作者,没有必要把文章的内容也获取出来(因为会转换成python对象,浪费内存)

Article.objects.all().defer(‘content’) # 注意这里没有查 content 字段了

7. only仅选择需要的字段

和 defer 相反,only 用于取出需要的字段,假如我们只需要查出 作者的名称

Author.objects.all().only(‘name’)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值