2011-08-09 24 views
8

この質問はまだ明らかに存在しないことに私は驚いています。もしそうなら、それを見つけるのを助けてください。Django条件付きの注釈

私はannotate(Count)とorder_byを使用したいと思いますが、関連するオブジェクトのすべてのインスタンスをカウントするのではなく、特定の基準を満たすインスタンスのみをカウントする必要はありません。

swallow.objects.annotate(num_coconuts=Count('coconuts_carried__husk__color = "green"').order_by('num_coconuts') 

答えて

8

これは正しい方法でなければなりません:私は、彼らが行われている緑色のココナッツの数でツバメを一覧表示するかもしれないとウィットに

、。

swallow.objects.filter(
    coconuts_carried__husk__color="green" 
).annotate(
    num_coconuts=Count('coconuts_carried') 
).order_by('num_coconuts') 

関連フィールドをフィルタリングすると、生のSQLではLEFT JOINとWHEREの両方に変換されます。最後に、注釈は、最初のフィルタから選択された関連する行のみを含む結果セットに対して作用します。ジャンゴ> = 1.8の場合

+0

確かにこれは動作するようには思えんが、ご指摘の理由のために、それは全く直感的です。私は、この質問セットが、色に関係なく運ばれたココナッツの総数によって命じられた少なくとも1つの緑色のココヤシを今まで運んできたすべての草を私に与えることを期待しています。 – jMyles

+1

@jMyles:ドキュメンテーションは、これは[annotateとfilter句の順序](https://docs.djangoproject.com/ja/1.3/topics/db/aggregation/#order-of-annotate- and-filter-clauses) - あなたの記述どおりに動作します。 –

+2

緑のココナッツを持っていないツバメを入れたい場合はどうすればいいですか? –

3

from django.db.models import Sum, Case, When, IntegerField 

swallow.objects.annotate(
    num_coconuts=Sum(Case(
     When(coconuts_carried__husk__color="green", then=1), 
     output_field=IntegerField(), 
    )) 
).order_by('num_coconuts')