有两个问题困扰着我,让我一直很好奇:
- QuerySet 惰性加载用了
Python
的什么特性来实现的?相关实现在Django
源码的哪个位置 - 还有就是
QuerySet
的缓存是如何实现的
我想着是通过重修某些特殊方法实现的
有两个问题困扰着我,让我一直很好奇:
Python
的什么特性来实现的?相关实现在 Django
源码的哪个位置QuerySet
的缓存是如何实现的我想着是通过重修某些特殊方法实现的
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
1 回答3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.5k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
复制 from https://blog.huguotao.com/post/django-lazy-query
原文如下:
Django QuerySets 如何实现惰性查询
Aug 07, 2016
最开始看 Django 官方文档时,关于 QuerySets 的介绍中有这么一段:
简单翻译:
什么是惰性查询
官方文档给了这样一个例子:
在以下情况时,QuerySets 才会进行数据库查询:
对其迭代,如:
对其使用带 step 的切片,如:
对其进行序列化或缓存,如:
对其使用 str() repr() len() list() bool() 等,如:
也就是说,QuerySets 只在需要取值时才进行数据库查询,惰性查询的实现除了避免不必要的数据库查询外,还可以支持链式过滤,方便进行更复杂的查询操作。
如何实现
QuerySets 是一个高度定制的类,在使用过程中有两个关键的步骤:
构造 SQL 语句这部分虽然复杂,但并不存在理解上的难点就不细说了,有意思的是第二步,QuerySets 是怎么知道什么时候要取值,并查询数据库的?这其中就用到了部分 Magic Methods (魔术方法)。
Magic Methods
Magic Methods 是 python 中很有趣的一部分,指那些前后被双下划线包围的特殊方法(如
__init__
),Magic Methods 有很多,今天主要介绍 QuerySets 中主要用到的几个关键方法:可以看见上面这几个 Magic Methods 分别对应了一种取值方式,取值时可以按需返回特定的值,所以通过这个例子很容易明白 QuerySets 在这些 Magic Methods 内都进行了这样一次判断,用 len 举例:
实际上每个 Magic Methods 内的实现还略有差别,但通过这样一次判断就可以实现在取值时才进行数据库查询从而达到了惰性查询的目的。
Reference