我有学生模型和入门模型。每个条目都有一个学生的外键,一个年票和两个数值(value1和value2)。我正在覆盖StudentAdmin类中的get_queryset()方法,并且使用Django ORM,我想要注释一个我们将调用的字段" specialvalue"。
学生每年最多只有一个参赛作品,但他们可能没有参赛作品,未来可能会有参赛作品。 "特殊值"的值对于当前年份的Entry,将等于Entry__value1减去Entry__value2。如果学生当年没有参赛作品,那么特殊价值将等于无,并且不会从查询集中删除这些学生。
我该怎么做?起初我尝试将查询集拆分为两个:
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)
我认为,使用Django条件表达式将适用于您的情况。有关更多信息,请阅读Case表达式(https://docs.djangoproject.com/en/1.11/ref/models/conditional-expressions/#case)。您只需检查条目是否与CURRENT_YEAR相关。
Case()接受任意数量的When()对象作为单独的参数。使用关键字参数提供其他选项。如果没有条件评估为TRUE,则返回使用default keyword参数给出的表达式。如果未提供默认参数,则使用None。
我没有测试过这个解决方案,但我认为它应该可行:
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')