比如说 books = Book.objects.all()
这一行代码并不会在运行时就取出所有数据
而是要到真正使用 books 时才会去取出数据
怎么做到的呢?原理是什么?
1
ss098 2017-07-08 16:25:45 +08:00
可能是魔术方法。
|
2
SP00F 2017-07-08 23:32:24 +08:00
Django 不熟,是异步吗 ……
|
3
Morriaty 2017-07-11 13:26:58 +08:00
没看过源码,我想到的一种可能实现是:
1、all()只是编译好了 sql,但没执行 2、orm object 的__iter__()方法才是真执行 sql 大致逻辑: class ORMObject(object): def all(self): self.sql = .... return self def filter(self, condition): self.sql = .... return self def __iter__(self): self.execute() |
4
Morriaty 2017-07-11 13:27:57 +08:00
哇 v 站评论不支持 markdown 也就罢了,还自动删减空格.........
|
5
daya0576 2017-07-12 01:13:05 +08:00 via iPad
楼上正解, 在执行这些魔术方法的时候去执行的 sql 并生成缓存:
Iteration, ie. 对 Queryset 进行 For 循环的操作. slicing, e.g. Entry.objects.all()[:5], 获取 queryset 中的前五个对象, 相当于 sql 中的 LIMIT 5 picling/caching repr/str len (Note: 如果你只想知道这个 queryset 结果的长度的话, 最高效的还是在数据库的层级调用 count()方法, 也就是 sql 中的 COUNT(). ) list() bool() 但调 queryset[5], values_list(), iterator()也会触发执行 sql, 但没有 cache 生成。 参考我的笔记: https://changchen.me/blog/20170503/django-performance-and-optimisation/ |