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

Django queryset-按**升序**获取最新结果,django,django-queryset,Django,Django Queryset,在Django中,如果我想按降序获得模型的最新10个实例,我可以这样做: MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10] 但如何按升序获取最近的10个实例?我知道我可以在从数据库中取出它们后在内存中重新排序: reversed(MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10]) 但我很好奇,是否有一种方法可以通过查询集来实现这一点 使用2个

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

MyModel.objects.order_by(‘-the_field_I_want_to_order_by’)[:10]
但如何按升序获取最近的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结果方面哪些可用/哪些不可用。

您可以使用切片表示法,正常情况下:

MyModel.objects.order_by('-the_field_I_want_to_order_by')[:10][::-1]
这样做的原因是最后一个片段没有被转换成SQL——它强制QuerySet求值并将其转换为列表。(这也意味着它不需要额外的查询。)


但是,这种方法效率较低,因为它强制创建与
MyModel.objects.all()大小相同的列表,谢谢大家的输入。一些人将答案作为评论发布,但不是作为答案。。。因此,这里是答案形式,便于以后查看:

答案似乎是否,您无法使用单个查询集以升序获得最新的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] 
或者您需要点击数据库两次(或者神奇地知道查询集中有多少项):


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

我现在想解决这个问题已经太迟了,但我认为
.reverse()
queryset方法可能会有所帮助。请看。除非我遗漏了什么,否则这正是
reverse()
文档所说的“Django不支持这种访问模式(从末尾切片),因为在SQL中不可能有效地执行它。”@Daniel-我试过了,但它只是在我的原始示例中取消“-”,然后返回前10个对象(即,它的行为就像我将.reverse()放在[:10]之前)。有点奇怪…@PeterdGlopper-如果是这样的话,那么也许你应该把你的评论作为答案而不是评论,这样它就可以被标记为被接受的答案(如果没有其他人提出不同的答案)。使用
[:-1]
相当于使用
反向
,正如OP所讨论的,但希望避免。两者都会反转内存中的结果集。这两种方法中的任何一种都可能是处理这个问题的最佳方法,所以我不认为这是关键性的。在阅读了注释中关于
queryset.reverse()
的讨论之后,我忘记了
reversed
的最初用法。但是,是的,这是一条路要走。在切片查询集中不支持负索引,因为正如Django文档所说,到SQL的转换结果非常难看(而且并不总是可能的)。顺便说一句,即使数据库为您这样做,它仍然在“内存中”反转,所以我不确定有什么折衷。
list(MyModel.objects.order_by('the_field_I_want_to_order_by'))[-10:]
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:]