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 = 5 # your choice
>>>
>>> m1 = Model.objects.filter(pk__gte=Model.objects.count() - limit) # last five
>>> m2 = Model.objects.filter(pk__lte=limit) # first five
现在您可以执行更多方法:
# Just for illustration
>>> m2.annotate(Avg("some_integer_column")) # annotate
>>> m2.annotate(Sum("some_integer_column"))
>>> m2.aggregate(Sum("some_integer_column")) # aggregate
8条答案
按热度按时间ygya80vv1#
Django查询集是懒惰的。这意味着只有当您明确要求结果时,查询才会命中数据库。
因此,在打印或实际使用查询结果之前,您可以在不访问数据库的情况下进一步过滤。
正如你在下面看到的,你的代码只执行了一个sql查询,只获取了最后10个项目。
yhived7q2#
实际上,我认为
LIMIT 10
将被发送到数据库,因此切片不会发生在Python中,而是发生在数据库中。更多信息请参见limiting-querysets。
ukxgm1gy3#
看起来问题中的解决方案不再适用于Django 1.7并引发错误:“获取切片后无法重新排序查询”
根据文档https://docs.djangoproject.com/en/dev/topics/db/queries/#limiting-querysets,强制Python切片语法的“step”参数计算Query。它是这样工作的:
我仍然想知道是否在SQL或Python中执行限制,将返回的整个结果数组切片。将巨大的列表检索到应用程序内存中是没有好处的。
ycggw6v24#
是的。如果你想获取对象的有限子集,你可以使用下面的代码:
示例:
开头的0是可选的,所以
上面的代码返回前10个示例。
koaltpgm5#
对
QuerySets
进行切片会返回一个list
,这意味着如果你喜欢:它将返回一个列表,问题是您无法在
list
上执行进一步的QuerySet
方法因此,如果你想对返回的结果做更多的事情,你可以这样做:
现在您可以执行更多方法:
通过使用slice表示法([])来限制结果,您还可以限制链接QuerySet方法的能力。
如果你非常确定你不需要做任何进一步的查询,那么切片就可以了。
628mspwn6#
过滤器问题的简单答案
只需输入
order_by
然后[:limit]
klh5stk17#
作为对其他有用答案的补充和观察,值得注意的是,实际执行
[:10]
作为切片将返回列表的前10个元素,而不是最后10个元素。要获得最后10个,您应该执行
[-10:]
(参见here)。这将帮助您避免将order_by('-id')
与-
一起使用来反转元素。55ooxyrt8#
Django 1.9.1
打印qs.query,查看LIMIT