2012-04-09 5 views
3

私は共通のクエリーセットをキャッシュしました。これは、状況に応じて異なるフィールドに基づいてフィルタリングしたいと思います。私は最初の場所でそれをキャッシュする利点を失う場合、評価されたクエリセットをフィルタリングすることによって疑問に思っています。 Djangoは、キャッシュされたクエリーセットの作成に関連するクエリーセットとそれ以降に適用するフィルタの集まりである別のクエリーセットを最初から作成しますか?Djangoは評価されたクエリーセットをフィルタリングする方法を教えてください。

答えて

5

はい、結果はスローされます。

ソースからこれを見ることができます:filter()_filter_or_exclude()が呼び出され、_clone()がコールされ、そのクエリに追加されます。 _clone、あなたは見ることができる、_result_cache属性を設定しません。

一般的に、共通の結果を維持するために可能性があることは明らかではありません。小さな結果セットを持つ複雑なクエリの場合、主キーが見つかった結果の1つであることを確認するSQLを発行するだけで置き換えることができますが、これは常に効率的になるとは限らず、場合によっては(データベースがキャッシュされてから追加のフィルタを実行するまでの間にクエリの結果に影響を与えるように変更された場合)意味がわかりにくくなります。

手動でIDを保存するこの動作を強制したい場合は、あなたがそれを行うことができます。

pks = SomeObject.objects.filter(...).values_list('pk', flat=True) 
some_of_them = SomeObject.objects.filter(pk_in=pks).filter(...) 
others = SomeObject.objects.filter(pk_in=pks).filter(...) 

あなたはまた、もちろん、単に、例えば、Pythonでフィルタリングを行うことができますこれらまたはクエリを再発行の1のサイズに多くを依存しているかどうか

common = SomeObject.objects.filter(...) 
some_of_them = [m for m in common if m.attribute == 'foo'] 
others = [m for m in common if m.other_attribute == 'bar'] 

(また、あなたは望ましい場合filter(lambda m: m.attribute == 'foo', common)を使用するか、より明確であることをlistcommonの定義をラップすることができます。)

によってフィルタの複雑さ、およびどのようなインデックスが存在しているかを示します。

関連する問題