django Queryset在for循环后成为List

时间:2015-06-03 09:17:30

标签: python django

我在我的网站上使用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循环中发生的事情感到困惑?

1 个答案:

答案 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   还会返回一个列表。