Gau*_*rav 3 django lazy-evaluation django-queryset
请考虑以下示例
data = Employee.objects.all()
for i in data:
print i.name
Run Code Online (Sandbox Code Playgroud)
从我在这里的低估,它为每个循环命中数据库.我不确定天气是对还是错.
下一个疑问是
data = Employee.objects.get(id=1)
Run Code Online (Sandbox Code Playgroud)
在这种情况下它会打到数据库吗?如果我将数据存储到另一个变量怎么办?
如果我做了
data = Employee.objects.all()
data1 = []
data1 = data
for i in data1:
print i
Run Code Online (Sandbox Code Playgroud)
上面和这个之间有什么区别?
这些get()
调用将立即打到数据库.将获取所有模型数据,并且在访问模型属性时不会访问数据库(除非它们是ForeignKeys
).如果已将其存储在另一个变量中,则不会以任何方式链接这些实例.例如:
var1 = Employee.objects.get(pk=1)
var2 = Employee.objects.get(pk=1)
var1.name = 'var1'
var2.name = 'var2'
var2.save()
print var1.name
>>> 'var1'
Run Code Online (Sandbox Code Playgroud)如果您想获取最新保存对象的版本,可以调用该refresh_from_db()
方法
var1.refresh_from_db()
var1.name
>>> 'var2'
Run Code Online (Sandbox Code Playgroud)
data1
变量访问查询集.它不会在赋值时进行评估,但会在迭代时进行评估.在第一种情况下,它将在 for 循环开始时访问数据库,更准确地说是在第一个循环时访问数据库。
在第二种情况下,它还不会访问数据库,因为尚未评估 QuerySet。查询集是惰性的,并且在以下情况下进行评估:
- 第一次迭代它们时
- 当你把它们切片时。例如:
Post.objects.all()[:3]
- 当您腌制或缓存它们时
- 当您致电
repr()
或len()
联系他们时- 当你明确地呼吁
list()
他们时- 当您在诸如 、 、 或 之类的语句中
bool()
测试or
它and
时if
摘自《Django by Example》一书,第 14 页。21
有关何时评估 QuerySet 的更多信息,请参阅文档。