模型:
class person(models.Model)
name = models.CharField()
...
如果我使用
persons = person.objects.order_by('name')[0:25]
在代码中,切片是在数据库级别(转换为 SELECT * FROM person ORDER BY name LIMIT 25)还是在“代码”级别执行的?
模型:
class person(models.Model)
name = models.CharField()
...
如果我使用
persons = person.objects.order_by('name')[0:25]
在代码中,切片是在数据库级别(转换为 SELECT * FROM person ORDER BY name LIMIT 25)还是在“代码”级别执行的?
是的,切片被翻译成 SQL 的LIMIT
.
我认为这取决于何时执行。
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.
这可能看起来微不足道,或者是一个边缘案例,但了解幕后发生的事情很重要。
这在文档中非常清楚(答案是肯定的):
使用 Python 数组切片语法的子集将 QuerySet 限制为一定数量的结果。这相当于 SQL 的 LIMIT 和 OFFSET 子句。