Django - 限制查询结果

krz*_*hub 180 django

我想获取模型的最后10个实例并拥有以下代码:

 Model.objects.all().order_by('-id')[:10]
Run Code Online (Sandbox Code Playgroud)

首先拿起所有实例然后只拿最后10个实例是真的吗?有没有更有效的方法?

ham*_*guz 278

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>]
Run Code Online (Sandbox Code Playgroud)


Dav*_*cic 34

实际上我认为LIMIT 10将发布到数据库,因此切片不会发生在Python中,而是发生在数据库中.

有关更多信息,请参阅limit-querysets.

  • 请注意,这对于也需要过滤的查询集不起作用,因为切片后无法过滤。 (2认同)
  • 因此,首先进行过滤,而不是切片。感谢Davor的链接! (2认同)

小智 12

看起来问题中的解决方案不再适用于Django 1.7并引发错误:"切片一旦切片就无法对查询重新排序"

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

Model.objects.all().order_by('-id')[:10:1]
Run Code Online (Sandbox Code Playgroud)

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


小智 7

是的。如果要获取有限的对象子集,可以使用以下代码:

例子:

obj=emp.objects.all()[0:10]
Run Code Online (Sandbox Code Playgroud)

开头的 0 是可选的,所以

obj=emp.objects.all()[:10]
Run Code Online (Sandbox Code Playgroud)

上面的代码返回前 10 个实例。