Django – 限制查询结果

我想采取模型的最后10个实例,并有这样的代码:

Model.objects.all().order_by('-id')[:10] 

是不是首先拿起所有的例子,然后只拿10个最后一个呢? 有没有更有效的方法?

Django查询集是懒惰的。 这意味着只有当你特别要求结果时,查询才会打到数据库。

因此,直到您打印或实际使用查询的结果,您可以进一步筛选,无需数据库访问。

正如你在下面看到的,你的代码只执行一个sql查询来只提取最后10个项目。

 In [19]: import logging In [20]: l = logging.getLogger('django.db.backends') In [21]: l.setLevel(logging.DEBUG) In [22]: l.addHandler(logging.StreamHandler()) In [23]: User.objects.all().order_by('-id')[:10] (0.000) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" ORDER BY "auth_user"."id" DESC LIMIT 10; args=() Out[23]: [<User: hamdi>] 

实际上,我认为LIMIT 10将被发布到数据库,所以在Python中不会发生切片,而是在数据库中。

有关更多信息,请参阅restrict-querysets 。

看起来问题中的解决scheme不再适用于Django 1.7,并引发了一个错误:“一旦一个切片被采取,不能重新排列查询”

根据文档https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets强制Python切片语法的“step”参数评估查询。; 它以这种方式工作:

 Model.objects.all().order_by('-id')[:10:1] 

仍然我不知道是否在SQL或Python切片中执行限制,整个结果数组返回。 将巨大的列表检索到应用程序内存是没有用的。

不,这是不正确的,正如文件中明确解释的那样。

这不是实际发生的事情。 Django不会只提取所需的结果。 Django会加载完整的数据库表(这是一个愚蠢的事情),只返回最后10条logging。

我已经通过在MySQL服务器上运行SHOW FULL PROCESSLIST来确认这一点,并且查询没有LIMIT子句。

如果您要开发一个需要高可伸缩性的大型应用程序,那么Django不是一个好select。