QuerySet的特性:惰性和缓存等

原创

QuerySet的特性:惰性和缓存等

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.youkuaiyun.com/makesomethings/article/details/99774127

对QuerySet的理解

是什么?(what)

QuerySet是Django的Model中的一种非常重要的概念, 在编写django项目时, 我们会经常用到这一概念. 因为后端的代码与数据库的所有交互都是通过它来完成的.

Model.objects.all()	# 最常见的queryset

     
     
  • 1

为什么要用?(why)

QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作. 在使用queryset获取数据库中的数据之前, 实际上没有发送任何数据库活动.

也就是说, 合理地利用queryset可以大大减少数据库的交互次数, 从而使程序能够以更高的效率执行

怎么用?(how)

QuerySet具有以下特性:

  1. 可切片
  2. 可迭代
  3. 惰性
  4. 缓存

可切片

可以使用python的切片语法来限制queryset记录的数目, 其作用等价于SQL的LIMITOFFSET子句。

>>> User.objects.all()[:5]      # (LIMIT 5)
>>> User.objects.all()[5:10]    # (OFFSET 5 LIMIT 5)

     
     
  • 1
  • 2

可迭代

QuerySet是可迭代类型,

>>> usersList=User.objects.all()

>>> for user in usersList:
print(user.name)

  • 1
  • 2
  • 3
  • 4

当您第一次对其进行迭代时,它将执行其数据库查询. 若之后还有语句访问相同的内容, 这可以直接加载, 不用再访问数据库, 这是其另一特性: 缓存

惰性

就像前面所说的query在被构造,切片等操作时不会对数据库操作, 这里就是queryset惰性, 也叫惰性查询

也就是说单纯的创建queryset

那么, 什么操作会使queryset进行数据库活动呢? 官方文档给出了我们很多例子:

  1. 迭代(Iteration), for i in queryset
  2. 切片(Slicing), 带有步长的切片, queryset[::2]
  3. 索引, queryset[0]
  4. 序列化/缓存化(Pickling/Caching), 将数据保存到redis中或者内存中的时候
  5. repr(). 直接打印, print(queryset)
  6. len(). len(queryset)
  7. list(). list(queryset)
  8. bool(). queryset if queryset else None

缓存

序列化缓存, 就是先将查询对象载入到内存中以完成序列化,这样你之后就可以第一时间使用对象(直接从数据库中读取数据需要一定时间,这正是缓存所想避免的)。

**序列化(Pickling)缓存化(Caching)**的先行工作,所以在缓存查询时,首先就会进行序列化工作。

这意味着当你反序列化 QuerySet 时,第一时间就会从内存中获得查询的结果,而不是从数据库中查找。

如何实现缓存? 先来来看一段代码:

>>> queryset = Model.objects.all()
>>> print(queryset[1]) # 访问了数据库
>>> print(queryset[1]) # 再次访问了数据库

 
 
  • 1
  • 2
  • 3

在这段代码中, 对queryset进行两次索引取值, 每一次取值查询, 都会访问数据库

但如果一次性将queryset中的全部值查询出来,若再次取值则将检查缓存

>>> queryset = Entry.objects.all()
>>> [entry for entry in queryset] # 访问了数据库
>>> print(queryset[1]) # 访问缓存
>>> print(queryset[1]) # 访问缓存

 
 
  • 1
  • 2
  • 3
  • 4

这就是最简单的缓存化方式

下面是一些其它例子,和上面的for循环相同的一点是, 它们会查询queryset中全部的值并填充到缓存中:

>>> [entry for entry in queryset]
>>> bool(queryset)
>>> entry in queryset
>>> list(queryset)

 
 
  • 1
  • 2
  • 3
  • 4

参考文章链接:QuerySet
更多内容请移步至官方文档:When QuerySets are evaluated

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet">
                </div>
</article>
<div class="postTime">
    <p class="article-bar-bottom"></p>
    <span>
        文章最后发布于: 2019年08月19日 23:04:06        </span>
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值