考虑以下示例
data = Employee.objects.all()
for i in data:
print i.name
从我的不足之处来看,它为每个循环命中数据库。我不确定天气是对还是错。
下一个疑问是
data = Employee.objects.get(id=1)
在这种情况下何时会命中数据库?如果我将数据存储到另一个变量怎么办?
如果我做了
data = Employee.objects.all()
data1 = []
data1 = data
for i in data1:
print i
上面和这个之间有什么区别?
答案 0 :(得分:8)
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'
如果您想获取最新保存对象的版本,可以调用refresh_from_db()
方法
var1.refresh_from_db()
var1.name
>>> 'var2'
data1
变量访问查询集。它不会在赋值时进行评估,但会在迭代时进行评估。答案 1 :(得分:2)
在第一种情况下,它将在for循环开始时命中数据库,更准确地说是在第一次循环时。
在第二种情况下,它还不会访问数据库,因为尚未对QuerySet进行评估。 QuerySets是惰性的,在以下情况下进行评估:
- 第一次迭代它们
- 当你切片时。例如:
Post.objects.all()[:3]
- 当您挑选或缓存它们时
- 当您致电
时repr()
或len()
- 当您明确呼叫
时list()
- 在
等语句中对其进行测试时bool()
,or
,and
或if
有关评估QuerySets的详细信息,请参阅docs。