2009-06-02 90 views
6

我从Foo模型中获取最新的5行,该模型由日期时间字段排序。django - 重新排序后切片查询集

qs = Foo.objects.all()[:5] 

在下面的步骤中,我要重新排序通过一些其它标准(实际上,通过在相反方向上的相同日期时间字段)的查询集。但不允许在切片之后重新排序。 reverse()解除了第一个排序,给了我一个不同的查询集。有没有一种方法可以实现我想要的功能,而无需从查询集创建列表并使用它进行排序?

回答

10

不,没有办法做到这一点。 order_by是数据库上的一项操作,但是当您对查询集进行切片时,将对其进行评估并在此后不返回数据库。

听起来像你已经知道的解决方案,但:运行reversed()对评估的问题。

qs = reversed(Foo.objects.all()[:5]) 
+0

所以我没有错过任何东西。谢谢。 – shanyu 2009-06-02 11:56:59

+0

我有同样的问题,并按照丹尼尔的建议,但发现我不能在查询集上使用count方法 – thchand 2012-02-08 21:20:27

13

order_by为您提供SQL数据库内排序。你已经在使用它,然后切片。在这一点上,结果被检索到内存中。如果你想改变它们的顺序,你需要使用Python内存中的排序来完成它,而不是ORM数据库内排序。

在你的情况,丹尼尔已经给出了最好的解决办法:因为你只是想通过相同的字段进行排序,但在另外的顺序,只是扭转你的列表:

qs = Foo.objects.all()[:5] 
objs = reversed(qs) 

如果你有希望通过一些其他的字段进行排序,那么你会用排序()函数的自定义按键功能:

qs = Foo.objects.all()[:5] 
objs = sorted(qs, key=lambda o: o.some_other_field) 
1

晚的答案,但是这只是为我工作:

import random 
sorted(queryset[:10], key=lambda x: random.random())