7

クラスには、同じ目的を果たしているように見える2つの異なるメソッドがあることがわかりますQuerySet(私が間違っていない限り):.__nonzero__.exists。(はい、私はそれ.__nonzero__がによって使用されていることを知っていboolます。)

私の質問:クエリセットにオブジェクトがあるかどうかを両方ともチェックするだけの場合、2つのメソッドの実装が異なるのはなぜですか?

Djangoのドキュメントには次のように書かれていQuerySet.__nonzero__ます:

注:少なくとも1つの結果が存在するかどうかを判断するだけで、実際のオブジェクトが必要ない場合は、これを使用しないでください。presents()を使用する方が効率的です(以下を参照)。

(「下」に洞察に満ちたものは何も見つかりませんでした。)

なぜQuerySet.__nonzero__非効率的な実装があるのですか?それとは違うことを成し遂げようとしているの.existsでしょうか?Django開発者がそうしない理由は何__nonzero__ = existsですか?

4

1 に答える 1

8

QuerySetを使用する理由。非ゼロは非効率的な実装を持っていますか?.existsとは異なる何かを達成しようとしていますか?Django開発者がゼロ以外の=存在しない理由は何ですか?

existsそれは特定の状況下でのみ効率的だからだと思います。

__nonzero__「効率的な」実装があった場合、この一般的なシナリオを想像してみてください。

foos = Foo.objects.filter(bar='baz')

if foos:   # nonzero() calls exists() which causes extra query
           # even though the QS is already going to be evaluated
           # which in my projects is a common pattern. 
   print "Yay for foos!"
   for foo in foos:
       print foo

__nonzero__また、クエリを評価し、結果をキャッシュに保存します。つまり、すべての結果がメモリに保存されます。

exists気にするのは1行だけで、djangoオブジェクトをインスタンス化したり、その結果をキャッシュに保存したりすることもありません。

何かが存在するかどうかをチェックするだけで、データをまったく必要としない場合に便利です。

なぜ開発者は__nonzero__==を作らないのexistsですか?

exists結果を気にしないと仮定しているからです。__nonzero__と呼ばれた場合exists、結果はありません。existsと呼ばれる場合__nonzero__、行が存在するかどうかを確認するためだけに結果(場合によっては大量)を収集します。

例:

bool( Foo.objects.filter(user=user) )  
# calls __nonzero__, evaluates, converts all fields to python objects 
# and stores in queryset._result_cache


Foo.objects.filter(user=user).exists()
# stores nothing, and query only returns one row.
# less data from DB and less python overhead generating django model instances.
于 2013-01-16T23:25:18.180 に答える