Django - limiting query results
我想获取模型的最后10个实例,并具有以下代码:
1 | Model.objects.all().order_by('-id')[:10] |
首先收集所有实例,然后只取最后10个实例,这是真的吗?还有更有效的方法吗?
Django查询集是懒惰的。这意味着只有当您特别要求结果时,查询才会命中数据库。
因此,在打印或实际使用查询结果之前,您可以在没有数据库访问的情况下进行进一步筛选。
正如您在下面看到的,您的代码只执行一个SQL查询来获取最后10个项目。
1 2 3 4 5 6 7 | 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>] |
实际上,我认为
有关详细信息,请参阅限制查询集。
似乎问题中的解决方案不再适用于Django 1.7,并引发错误:"获取切片后无法对查询重新排序"
根据文档https://docs.djangoproject.com/en/dev/topics/db/queries/limiting queryset强制使用python slice语法的"step"参数来评估查询。它是这样工作的:
1 | Model.objects.all().order_by('-id')[:10:1] |
不过,我想知道这个限制是在SQL还是Python中执行的,它将返回整个结果数组切片。在应用程序内存中检索巨大的列表是没有好处的。
对。如果要获取对象的有限子集,可以使用以下代码:
例子:
1 | obj=emp.objects.all()[0:10] |
开头0是可选的,因此
1 | obj=emp.objects.all()[:10] |
上面的代码返回前10个实例。
作为对其他有用答案的补充和观察,值得注意的是,实际执行EDOCX1[1]作为切片将返回列表的前10个元素,而不是最后10个元素…
为了得到最后10个,你应该改为使用
事实并非如此。Django不只获取所需的结果。Django将加载完整的数据库表(这是一个愚蠢的[id操作),并只返回最后10条记录。
我已经通过在mysql服务器上运行show full processlist确认了这一点,并且查询没有limit子句。
如果要开发一个需要高可伸缩性的大型应用程序,Django不是一个好的选择。