0

模型:

class person(models.Model)
    name = models.CharField()
    ...

如果我使用

persons = person.objects.order_by('name')[0:25]

在代码中,切片是在数据库级别(转换为 SELECT * FROM person ORDER BY name LIMIT 25)还是在“代码”级别执行的?

4

3 回答 3

1

是的,切片被翻译成 SQL 的LIMIT.

于 2013-03-14T06:47:13.853 回答
1

我认为这取决于何时执行。

Django 的 ORM QuerySet 是“惰性的”,因为它们在被迭代之前不会真正运行。这使您可以执行以下操作:

persons = person.objects.filter(age__gte=25)
persons = persons.filter(age__lte=50)
persons = persons.exclude(age=30)
persons = persons.order_by('name')
persons = persons[:25]
for person in persons:
    print person.name

意思是“让所有 25 岁以上、50 岁以下的人(不包括 30 岁的人)按他们的名字排序,并给我前 25 条记录。

因为它是惰性的,所以当您实际进入循环QuerySet时,所有这些代码只会创建一个数据库调用。for

所以,是的,从技术上讲,当 ORM 进入循环时,order_by 转换为 LIMIT。

然而,ORM 在幕后所做的是为数据库返回的每条记录创建一个 Python 列表。所以,假设我们在上述之后继续:

for person in persons: # SQL command is compiled and run, with a list returned
    print person.name
persons = persons[:10] # Django just slices the list we already have in memory.

这可能看起来微不足道,或者是一个边缘案例,但了解幕后发生的事情很重要。

于 2013-03-14T07:30:31.687 回答
1

这在文档中非常清楚(答案是肯定的):

使用 Python 数组切片语法的子集将 QuerySet 限制为一定数量的结果。这相当于 SQL 的 LIMIT 和 OFFSET 子句。

于 2013-03-14T08:14:15.323 回答