我想在查询集上有一个字段status
,该字段是根据一组预取的反馈值的函数得出的。
反馈示例:
feedback = [
{'action': 0, 'user': 1},
{'action': 1, 'user': 13},
]
如果我是在Serializer上编写的,我会这样做:
def get_status(self, obj):
# Squash all feedback into single status value
fb = obj.feedback.all()
vals = [f.action for f in fb]
if len(vals) == 0:
return 0 # Unconfirmed
if sum(vals) == 0:
return 1 # Confirmed
return 2 # Rejected
不过,我想将此逻辑下移到视图的查询集中以启用对该字段的排序。
queryset = Foo.objects\
.prefetch_related('feedback')\
.annotate(status="???")
我想知道哪些可用的查询表达式集可以模仿上面的python函数get_status
的逻辑。
答案 0 :(得分:2)
由于数据库层不了解函数,因此无法在.annotate(..)
中调用函数。您可以尝试将以上内容转换为表达式。您不需要为此需要.prefetch_related(..)
。在这里您可以使用Case
[Django-doc]和When
[Django-doc]:
from django.db.models import Case, Count, IntegerField, Sum, Value, When
queryset = Foo.objects.annotate(
nfeedback=Count('feedback'),
sumfeedback=Sum('feedback__action')
).annotate(
status=Case(
When(nfeedback=0, then=Value(0)),
When(sumfeedback=0, then=Value(1)),
default=Value(2),
output_field=IntegerField()
)
)