我在我的网站上使用django,问题很难说,请看下面的代码。(python 2.7.10)
In [1]: user = User.objects.filter(pk__gt = 1)
In [2]: type(user)
Out[2]: django.db.models.query.QuerySet
In [3]: user1=user[0:user.count()]
In [4]: type(user1)
Out[4]: django.db.models.query.QuerySet
显然,user和user1是QuerySet,现在问题出现了:
In [1]: user = User.objects.filter(pk__gt = 1)
In [2]: type(user)
Out[2]: django.db.models.query.QuerySet
In [3]: for i in user:pass
In [4]: user1=user[0:user.count()]
In [5]: type(user1)
Out[5]: list
用户也是QuerySet,但user1成为列表。
这两个代码唯一不同的是for循环
for i in user:pass
我对for循环中发生的事情感到困惑?
答案 0 :(得分:4)
通过运行for
循环,您可以执行Django调用评估 QuerySet
的内容。在此之前,它被认为是 lazy ,这意味着添加过滤器和其他QuerySet
方法实际上并没有访问数据库。
来自QuerySets are lazy的一个有趣的片段(也参见那里的例子):
QuerySets是懒惰的 - 创建QuerySet的行为不涉及 任何数据库活动。你可以整天堆叠过滤器, 在QuerySet之前,Django实际上不会运行查询 评价。
有一些评估QuerySet
的语句和方法,这些语句和方法记录在When QuerySets are evaluated中,包括迭代和切片已评估的QuerySet
。
这意味着,一旦您 评估 一个查询集,例如通过使用for
循环进行的迭代,Django将实际查询数据库。完成后,文档中的这一段总结了您在第二个shell片段中QuerySet
user1=user[0:user.count()]
与In [4]
切片后得到的行为。
切片。如限制QuerySet中所述,可以对QuerySet进行切片, 使用Python的数组切片语法。切片未评估的QuerySet 通常返回另一个未评估的QuerySet,但Django将执行 数据库查询,如果使用切片语法的“step”参数, 并将返回一个列表。 切片已评估的QuerySet 还会返回一个列表。