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。