如何在Django中从QuerySet获取倒数第二个项目?

3
如何从Django QuerySet中获取倒数第二个项目?我尝试了以下代码:my_queryset[-2](在检查my_queryset长度大于1之后)。
if len(my_queryset)>1:
     query = my_queryset[-2]

并且返回:

异常值:不支持负索引。

有没有“Django”的方法来获取这样的项?

我能想到的唯一一件事是反转查询集并获取 my_queryset[2] 但我不确定它的效率。

编辑:

scans = self.scans.all().order_by('datetime')
if len(scans)>1:
    scan = scans[-2]

你想获取哪个项目?如果您能告诉我们查询集构建的逻辑,将更好地理解您的需求,并帮助我们为您提供帮助。 - AKS
我已经编辑了答案并在底部添加了代码。我唯一想要的是不获取最后一个项目,而是获取倒数第二个项目。 - Milano
1
请查看此帖子:Django-如何在查询集中获取倒数第二条记录?。至于排序,如果您按降序排序,则不会对效率产生任何影响。 - AKS
1
反转查询集与按原始顺序排序相比并不会导致性能问题——只要在排序列上有索引(或数据集足够小),无论是正向还是反向,都可以快速完成。 - Risadinha
1
请注意,len(my_queryset) 会导致 Django 加载整个 queryset。对于较大的 queryset,这可能非常缓慢,因此您可以改用 my_queryset.count()。或者,根本不使用 count()len(),尝试获取 scans[x],然后捕获可能的 IndexError - Alasdair
1个回答

6

这段代码会产生错误

scans = self.scans.all().order_by('datetime')
if len(scans)>1:
    scan = scans[-2]

这相当于

scans = self.scans.all().order_by('-datetime')
if len(scans)>1:
    scan = scans[1]

如果你想获取第二个索引,需要使用索引1而不是2,因为在Python中偏移量从0开始。
另外注意,Django查询集是延迟加载的,这意味着如果有适当的索引可用,你可以改变排序方式而不会有性能损失。
引用块中提到:“查询集是懒加载的——创建查询集并不涉及任何数据库活动。你可以一整天地堆叠过滤器,Django直到查询集被评估才会实际运行查询。看看这个例子:”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接