2017-06-11 15 views
0

私はStudentモデルとEntryモデルを持っています。各エントリには、学生への外部キーと、年スタンプと、2つの数値(value1とvalue2)があります。私はStudentAdminクラスのget_queryset()メソッドをオーバーライドしており、Django ORMを使用して、 "specialvalue"と呼ばれるフィールドに注釈を付ける必要があります。フィルタなしのDjango条件付き注釈

学生は各年に最大1つのエントリがありますが、それらは存在しない可能性があります。また、今後数年間エントリがあるかもしれません。 "specialvalue"の値は、今年のエントリのEntry__value1からEntry__value2を差し引いたものに等しくなります。生徒に今年の入学がない場合、specialvalueはNoneに等しくなり、これらの生徒はクエリーセットから削除されません。

どうすればいいですか?最初に私は二つにクエリセットを分割しようとした:

queryset_1 = queryset.filter(entry__year=THIS_YEAR).annotate(specialvalue=...) 
queryset_2 = queryset.exclude(entry__year=THIS_YEAR).annotate(specialvalue=Value(None)) 

して、それらを別々に注釈を付けると、それらをマージ|残念ながらこれはknown bug in Django's ORMのため誤った結果になります。

ありがとうございました!

+0

あなたの学生およびエントリモデル構造 –

+0

@NeErAjKuMaRが、私は、関連するすべてのものがあると思います。各エントリには、学生への外部キー、年フィールド、および値1および値2のフィールドがあります。各生徒は名前などの無関係のフィールドをいくつか持っています。それ以外のものがある場合は、それを含めて私に知らせてください。ありがとう。 – jediahkatz

答えて

0

Djangoの条件式を使用すると、あなたのケースでは適用可能な解決策になると思います。詳細については、ケース式をお読みください(https://docs.djangoproject.com/en/1.11/ref/models/conditional-expressions/#case)。エントリがCURRENT_YEARに関連しているかどうかを確認するだけです。

Case() accepts any number of When() objects as individual arguments. Other options are provided using keyword arguments. If none of the conditions evaluate to TRUE, then the expression given with the default keyword argument is returned. If a default argument isn’t provided, None is used.

私はこのソリューションをテストしていないが、私はそれが動作するはずだと思う:

from django.db.models import Case, When, F, IntegerField 
queryset = queryset.annotate(
    specialvalue=Case(
     When(entry__year=THIS_YEAR, 
      then=F('entry__value1') - F('entry__value2') 
     ), output_field=IntegerField() 
    ) 
).values_list('specialvalue') 
+0

残念ながら私はこれを試してみました。タイプエラー:.values()または.values_list()の後にselect_related()を呼び出せません。 – jediahkatz

関連する問題