是否在数据库级别上执行了模型查询集上使用的python切片语法?

时间:2013-03-14 06:40:29

标签: django django-models

模型:

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

如果我使用

persons = person.objects.order_by('name')[0:25]
代码中的

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

3 个答案:

答案 0 :(得分:1)

是的,切片被转换为SQL的LIMIT

答案 1 :(得分:1)

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

Django的ORM QuerySets是“懒惰的”,因为它们实际上不会运行,直到它们被迭代。这可以让你做到这样的事情:

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.

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

答案 2 :(得分:1)

这一点非常明确in the documentation(答案是肯定的):

  

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