QuertSet的懒加载 与 缓存

一、QuertSet的懒加载

每个 QuerySet都带有缓存,这样可以尽量减少数据库访问。理解它是如何工作的能让你编写更高效的代码。

新创建的 QuerySet缓存是空的。一旦要计算 QuerySet的值,就会执行数据查询,随后,Django 就会将查询结果保存在 QuerySet的缓存中,并返回这些显式请求的缓存(例如, 对QuerySet迭代)。后续针对 QuerySet的计算会复用缓存结果。

1.什么时候发起sql请求,并缓存数据

QuerySet的结果集存储在_result_cache属性中。我们可以查看_result_cache来确定缓存了数据。

数据模型:

# models.py
class Student(models.Model):
    username = models.CharField('学生姓名', max_length=16)
    age = models.IntegerField('年龄')
    
    def __str__(self):
        return self.username
    
    def __repr__(self):
        return self.__str__()
>>> query_set = Student.objects.all()
>>> print(query_set._result_cache)
>>> None

直接打印缓存,可以看的,缓存结果为 None,说明没有缓存,只有执行计算才会进行缓存。

当执行以下计算时,django会发送sql请求,并缓存数据。

  • len()计算长度
  • bool 判断, 这里本质上是调用len判断长度是否大于 0
  • 迭代
  • 打印 print / repr
  • Pickling序列化
  • 转化为list -> list(query_set)

我们一般用的最多的就是迭代
如下:

>>> from api.models import Student
>>> query_set = Student.objects.all()

当我们生成query_set时,查看pycharm自带的调试工具

截屏2020-05-0810.32.18.png

可以看出此时的query_set_result_cacheNone
备注:可以通过query属性看出拼接出来的sql语句:

SELECT "api_student"."id", "api_student"."username", "api_student"."age" FROM "api_student"

当我们执行

>>> list(query_set)
截屏2020-05-0810.37.09.png

可以看出query_set的最新属性变化,_result_cache变成了一个list序列,缓存这我们查询出来的数据。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。