Django queryset - 以**升序**顺序获取最新结果

时间:2014-04-18 21:20:10

标签: django django-queryset

在Django中,如果我想以DESCENDING顺序获取模型的最新10个实例,我可以这样做:

MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10]

但是如何以ASCENDING顺序获取最新的10个实例?我知道从数据库中提取它们后我可以在内存中对它们进行重新排序:

reversed(MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10])

但我很好奇是否有办法只使用查询集。

使用2个查询,我想我可以做类似的事情:

count = MyModel.objects.count()
MyModel.objects.order_by(‘the_field_I_want_to_order_by’)[count-10:]

但是如果可能的话,用一个查询来获取它会很好。


修改
只是为了澄清,我并不是说上述技术太慢,或者说不可接受,或者需要避免。这个问题的目的只是通过QuerySet API找出什么是/不可用的,以便按升序获得最新的X结果。

2 个答案:

答案 0 :(得分:2)

您可以像往常一样使用切片表示法:

MyModel.objects.order_by('-the_field_I_want_to_order_by')[:10][::-1]

原因是最后一个切片没有被转换为SQL - 它强制QuerySet进行评估并将其转换为列表。 (这也意味着它不需要额外的查询。)

>>> type(MyModel.objects.order_by('-the_field_I_want_to_order_by')[:10])
<class 'django.db.models.query.QuerySet'>
>>> type(MyModel.objects.order_by('-the_field_I_want_to_order_by')[:10][::-1])
<type 'list'>

在Python 2.7上测试Django 1.5。

您也可以使用第二种方法,只使用一种类似策略的查询(强制评估列表):

list(MyModel.objects.order_by('the_field_I_want_to_order_by'))[-10:]

这种方式效率较低,因为它强制创建与MyModel.objects.all()大小相同的列表。

答案 1 :(得分:1)

感谢大家的投入。有几个人将答案作为评论发布,但不是答案......所以这里的答案形式是为了以后更容易看到:

似乎答案是 NO,您无法使用单个QuerySet以升序获得最新的X结果,因为Django不支持从末尾开始切片。结果需要在内存中重新排序:

reversed(MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10])

# or, reorder in memory using the technique suggested by Two-Bit Alchemist:
MyModel.objects.order_by('-the_field_I_want_to_order_by')[:10][::-1] 

或者你需要两次点击数据库(或者以某种方式神奇地知道你的查询集中有多少项):

qs = MyModel.objects.order_by(‘the_field_I_want_to_order_by’)
count = qs.count()
MyModel.objects.order_by(‘the_field_I_want_to_order_by’)[count-10:]

除非您从数据库中检索TON项目,否则前一种技术可能不仅更简洁,而且效率更高。