代码之家  ›  专栏  ›  技术社区  ›  Deniz Dogan

获取查询集中元素的索引

  •  35
  • Deniz Dogan  · 技术社区  · 15 年前

    我有一个查询集,我们称之为 qs ,它由一些与此问题无关的属性排序。那么我有一个物体,我们叫它 obj . 现在我想知道什么指数 OBJ 有在 QS 作为 有效地 尽可能。我知道我可以用 .index() 从python或者可能循环通过 QS 将每个对象与 OBJ 但是做这个最好的方法是什么?我在寻找高性能,这是我唯一的标准。

    在Windows上使用python 2.6.2和django 1.0.2。

    5 回复  |  直到 11 年前
        1
  •  16
  •   rob    15 年前

    Django中的查询集实际上是生成器,而不是列表(有关详细信息,请参见 Django documentation on QuerySets )
    因此,没有捷径可以获取元素的索引,我认为一个简单的迭代是最好的方法。

    对于初学者,我将以最简单的方式实现您的需求(比如迭代);如果您确实有性能问题,那么我将使用一些不同的方法,比如用较小的字段构建一个查询集,或者其他任何方法。
    在任何情况下,当你明确知道自己需要这些技巧时,你的想法就是尽可能晚地留下这些技巧。
    更新: 您可能需要直接使用一些SQL语句来获取行数(一些谎言)。但是,Django的ORM本机不支持此功能,您必须使用原始SQL查询(请参见 documentation )。我认为这可能是最好的选择,但再一次-只有当你真正看到一个真正的性能问题。

        2
  •  57
  •   drdaeman    15 年前

    紧凑型,可能是最有效的:

    for index, item in enumerate(your_queryset):
        ...
    
        3
  •  29
  •   Richard    12 年前

    如果您只想知道对象在所有其他对象中的位置(例如,在确定排名时),您可以通过在您之前计算对象来快速完成:

        index = MyModel.objects.filter(sortField__lt = myObject.sortField).count()
    
        4
  •  12
  •   Vinay Sajip    15 年前

    假设为了说明,您的模型是带主键的标准模型 id ,然后评估

    list(qs.values_list('id', flat=True)).index(obj.id)
    

    将找到的索引 obj 在里面 qs . 而使用 list 计算查询集,它不计算原始查询集,而是计算派生的查询集。此计算运行SQL查询仅获取ID字段,而不浪费时间获取其他字段。

        5
  •  2
  •   Jiaaro    11 年前

    你可以用 queryset.extra(…) 还有一些原始的SQL,比如:

    queryset = queryset.order_by("id")
    record500 = queryset[500]
    
    numbered_qs = queryset.extra(select={
        'queryset_row_number': 'ROW_NUMBER() OVER (ORDER BY "id")'
    })
    
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute(
        "WITH OrderedQueryset AS (" + str(numbered_qs.query) + ") "
        "SELECT queryset_row_number FROM OrderedQueryset WHERE id = %s",
        [record500.id]
        )
    index = cursor.fetchall()[0][0]
    
    index == 501 # because row_number() is 1 indexed not 0 indexed