48

私はQuerySetを持っています、それを呼びましょうqs。これは、この問題に関係のないいくつかの属性によって順序付けられています。それから私はオブジェクトを持っています、それを呼びましょうobjここで、可能な限り効率的に、どのインデックスobjが含まれているのかを知りたいと思います。Pythonから使用したり、各オブジェクトをと比較してループしたりできることは知っていますが、これを行うための最良の方法は何ですか?私は高性能を探しています、そしてそれは私の唯一の基準です。qs.index()qsobj

Windows上のDjango1.0.2でPython2.6.2を使用する。

4

6 に答える 6

65

すでにクエリセットを反復処理していて、現在使用している要素のインデックスを知りたいだけの場合、コンパクトでおそらく最も効率的なソリューションは次のとおりです。

for index, item in enumerate(your_queryset):
    ...

ただし、クエリセットと無関係な方法で取得したオブジェクトがあり、クエリセット内のこのオブジェクトの位置を知りたい場合は、これを使用しないでください(存在する場合)。

于 2009-06-25T07:50:35.197 に答える
46

オブジェクトが他のすべての中でどこにあるかを知りたいだけの場合(ランクを決定するときなど)、前にオブジェクトを数えることですばやく行うことができます。

    index = MyModel.objects.filter(sortField__lt = myObject.sortField).count()
于 2013-02-08T12:13:05.180 に答える
24

DjangoのQuerySetは実際にはジェネレーターであり、リストではありません(詳細については、QuerySetsに関するDjangoのドキュメントを参照してください)。
そのため、要素のインデックスを取得するためのショートカットはありません。単純な反復がそれを行うための最良の方法だと思います。

手始めに、私はあなたの要件を可能な限り簡単な方法で実装します(反復など)。本当にパフォーマンスの問題がある場合は、フィールドの数が少ないクエリセットを作成するなど、別のアプローチを使用します。
いずれにせよ、あなたがそれらを必要としていることを確実に知っているとき、アイデアはそのようなトリックをできるだけ遅く残すことです。
更新:行番号を取得するためにSQLステートメントを直接使用することをお勧めします(何かがあります。ただし、DjangoのORMはこれをネイティブにサポートしていないため、生のSQLクエリを使用する必要があります(ドキュメントを参照)。これが最良のオプションであると思います。 、ただし、実際のパフォーマンスの問題が実際に発生した場合に限ります。

于 2009-06-25T07:43:46.130 に答える
23

説明の目的で、モデルが主キーを備えた標準であると想定し、id評価します。

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

objのインデックスが見つかりますqs。を使用するとクエリセットが評価されますlistが、元のクエリセットではなく派生クエリセットが評価されます。この評価では、SQLクエリを実行して、idフィールドのみを取得し、他のフィールドのフェッチに時間を浪費しません。

于 2009-06-25T15:22:17.907 に答える
6

クエリセット内の要素のインデックスをクエリする簡単なpythonicの方法が可能です。

(*qs,).index(instance)

この回答は、クエリセットをリストに解凍し、組み込みのPythonインデックス関数を使用してその位置を決定します。

于 2019-03-06T17:03:40.957 に答える
4

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
于 2014-01-30T20:17:59.167 に答える