一、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
自带的调试工具
可以看出此时的
query_set
的_result_cache
为 None
备注:可以通过
query
属性看出拼接出来的sql
语句:
SELECT "api_student"."id", "api_student"."username", "api_student"."age" FROM "api_student"
当我们执行
>>> list(query_set)
可以看出query_set
的最新属性变化,_result_cache
变成了一个list
序列,缓存这我们查询出来的数据。