【问题标题】:How to get penultimate item from QuerySet in Django?如何从 Django 中的 QuerySet 中获取倒数第二个项目?
【发布时间】:2016-12-08 12:08:57
【问题描述】:

如何从 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]

【问题讨论】:

  • 你想买什么?如果您能告诉我们构建查询集的逻辑,它将更好地理解您想要什么,并帮助我们帮助您。
  • 我已经编辑了答案并在底部添加了一个代码。我唯一想要的不是获得最后一项,而是获得最后一项。
  • 请查看此帖子:Django- How to get second last record in a queryset?。至于排序,降序排序对效率没有任何影响。
  • 反转查询集与按原始顺序排序相比不再是性能问题 - 只要您在排序列上有索引(或数据集足够小),它在任一方向上都很快.
  • 请注意,len(my_queryset) 将导致 Django 加载整个查询集。对于较大的查询集,这可能会非常慢,因此您可以改用my_queryset.count()。或者,根本不要使用count()len(),尝试获取scans[x],然后捕获可能的IndexError

标签: python django django-models django-queryset


【解决方案1】:

产生错误的代码

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 querysets are lazy,这意味着您可以在不影响性能的情况下改变主意,前提是提供适当的索引。

QuerySet 是惰性的——创建 QuerySet 的行为不涉及 任何数据库活动。您可以整天将过滤器堆叠在一起, 并且 Django 不会真正运行查询,直到 QuerySet 是 评估。看看这个例子:

【讨论】:

    猜你喜欢
    • 2016-09-25
    • 2021-08-23
    • 2022-08-09
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2017-10-27
    相关资源
    最近更新 更多