天天都用到的东西,天天查.写一行代码就来这里查一次.

QuerySet 本身可以被构造,过滤,切片,或者复制赋值等,是无需访问数据库的。只有在你需要从数据库取出数据或者,向数据库存入数据时才需要访问数据库。

你可以用以下方式执行一个 QuerySet:

1.迭代。

一个 QuerySet 是可迭代的,当你第一次迭代它时,它就会执行其数据库查询。例如,这将打印数据库中所有条目的标题:

  1. for e in Entry.objects.all():
  2. print(e.headline)

注意:如果你想做的只是确定至少一个结果是否存在,不要使用这个。使用 exists() 会更有效。

2.切片。

正如在 限制 QuerySet 条目数 中所解释的那样,QuerySet 可以使用 Python 的数组切片语法进行切片。切片一个未执行的 QuerySet 通常会返回另一个未执行的 QuerySet,但如果使用切片语法的 step 参数,Django 会执行数据库查询,并返回一个列表。切片一个已经执行过的 QuerySet 也会返回一个列表。

还要注意的是,即使对一个未执行的 QuerySet 进行切片,返回另一个未执行的 QuerySet,也不允许进一步修改它(例如,添加更多的过滤器,或修改排序),因为这不能很好地翻译成 SQL,也没有明确的含义。

3.Pickle 序列化/缓存。

关于 pickling QuerySets 时涉及的细节,请参见下一节。就本节而言,重要的是,结果是从数据库中读取的。

4.repr()。

当你调用 repr() 时,所在 QuerySet 会被执行。这是为了方便 Python 交互式解释器,所以当你交互式使用 API 时,可以立即看到你的结果。

5.len()。

当你调用 len() 时,会执行 QuerySet。正如你所期望的,这将返回结果列表的长度。

注意:如果你只需要确定集合中的记录数(而不需要实际的对象),那么使用 SQL 的 SELECT COUNT(*) 在数据库层面上处理计数会更有效率。Django 提供了一个 count() 方法正是为了这个原因。

6.list()。

通过调用 list() 强制执行 QuerySet。例如:

  1. entry_list = list(Entry.objects.all())

7.bool()。

在布尔语境中测试 QuerySet,如使用 bool()、or、and 或 if 语句,将导致查询被执行。如果至少有一个结果,则 QuerySet 为 True,否则为 False。例如:

  1. if Entry.objects.filter(headline="Test"):
  2. print("There is at least one Entry with the headline Test")

注意:如果你只想确定至少一个结果是否存在(而不需要实际的对象),使用 exences() 更高效。