class Forecast(Model):
id = UUID()
type = StringField()
approved = BooleanField()
我想通过在批准的字段上应用“逻辑和”来对字段type
进行分组。假设带注释的字段为all_approved
。如果所有具有该类型的项目均为True,则all_approved
应该为True,如果至少一项为False,则{false}。
因此,最终我希望在查询集中拥有两个字段type
,all_approved
。
我该如何实现?
我尝试了基于this answer的内容,但什么也没得到。
编辑:
当我尝试该答案中给出的内容时,它没有执行“逻辑与”操作。取而代之的是,对于每个type
,它只给出两项,一项以all_approved
为True,另一项以all_approved
为False。我希望每个type
都有一个项目。
我也不明白为什么这个答案应该起作用。在哪里指定在分组时是否应该执行“逻辑与”或“逻辑或”。
答案 0 :(得分:3)
其他解决方案:您可以尝试将所有approved
与approved=True
from django.db.models import Count, Case, When, BooleanField
Forecast.objects.values(
'type'
).annotate(
cnt_app=Count(Case(When(approved=True, then=1)))
).annotate(
all_approved=Case(
When(cnt_app=Count('approved'), then=True),
default=False,
output_field=BooleanField()
)
).values('type', 'all_approved')
其中
Count(Case(When(approved=True, then=1)))
为我们提供了类型为True的已批准计数,
Count('approved')
给出了该类型的总数,
如果值相等,则all_approved为True,否则为False
答案 1 :(得分:2)
对于具有至少一个all_approved
值的类型,您可以使用子查询将False
翻转到False
:
from django.db.models import BooleanField
from django.db.models.expressions import Case, When
(Forecast.objects
.annotate(all_approved=Case(
When(type__in=Forecast.objects.filter(approved=False).values('type'),
then=False),
default=True,
output_field=BooleanField()
))
.values('type', 'all_approved')
.distinct()
)
您链接的question有点不同,因为它与Django自动加入的两个模型之间的一对多关系有关。
在这里,您只有一个模型,您必须将其自身结合起来才能使用相同的解决方案。由于Django仅支持由关系定义的联接,因此您需要使用子查询作为解决方法。