【问题标题】:Django annotate on boolean FieldDjango在布尔字段上注释
【发布时间】:2019-09-03 03:44:09
【问题描述】:
class Forecast(Model):
    id = UUID()
    type = StringField()
    approved = BooleanField()

我想通过在已批准字段上应用“逻辑和”来对字段 type 进行分组。假设带注释的字段是all_approvedall_approved 应该是 True 如果该类型的所有项目都为 True,如果至少一个为 False,则为 false。

所以最后在我的查询集中我想要两个字段typeall_approved

我怎样才能做到这一点?

我尝试了基于this answer 的东西,但什么都得不到。

编辑:

当我尝试该答案中给出的内容时,它没有执行“逻辑与”。而对于每个type,它只给出两项,一项以all_approved 为真,另一项以all_approved 为假。我希望每个 type 都有一个项目。

我也不明白为什么这个答案应该有效。如果在分组时应该执行“逻辑与”或“逻辑或”,则在哪里指定。

【问题讨论】:

  • 请根据您的数据展示您的尝试和错误,因为在您链接的答案中有一个很好的例子。
  • @BearBrown 编辑了答案
  • 在您链接的文章中,他们使用 Count 进行聚合。但我找不到任何对布尔字段起作用的 Django 数据库函数。例如,我尝试了 Min(),但它失败了。
  • 我添加了答案,我尝试在放置链接时说出我的意思

标签: django postgresql django-queryset


【解决方案1】:

其他解决方案:您可以尝试将所有approvedapproved=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

【讨论】:

    【解决方案2】:

    对于至少具有一个 False 值的类型,您可以使用子查询将 all_approved 翻转为 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 仅支持由关系定义的连接,因此您需要子查询作为解决方法。

    【讨论】:

    • type 是一个字符串字段。我想要的是批准的注释。这行不通。
    • So finally in my queryset i want to have two fields type, all_approved.
    • 更新了答案以提供所请求的两列。
    猜你喜欢
    • 2015-09-19
    • 2019-07-21
    • 2021-03-08
    • 2017-07-25
    • 2018-03-21
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    • 2019-01-22
    相关资源
    最近更新 更多