如何使用 Django ORM 将注释字符串转换为布尔值

Posted

技术标签:

【中文标题】如何使用 Django ORM 将注释字符串转换为布尔值【英文标题】:How to convert with annotate String to Bool with Django ORM 【发布时间】:2020-04-11 22:51:03 【问题描述】:

我的问题如下。有要求

Thread.objects.all().annotate(is_marked=Count('mark', Q(mark__username='gou')))

在 SQL 中看起来像这样

SELECT "api_thread"."id",
       "api_thread"."conference_id",
       "api_thread"."title",
       "api_thread"."description",
       "api_thread"."is_closed",
       "api_thread"."is_hidden",
       "api_thread"."is_pinned",
       "api_thread"."has_voting",
       "api_thread"."creator_uid",
       "api_thread"."created_at",
       "api_thread"."expired",
       COUNT("api_thread_mark"."user_id") FILTER (WHERE "auth_user"."username" = 'gou') AS "is_marked"
FROM "api_thread"
         LEFT OUTER JOIN "api_thread_mark" ON ("api_thread"."id" = "api_thread_mark"."thread_id")
         LEFT OUTER JOIN "auth_user" ON ("api_thread_mark"."user_id" = "auth_user"."id")
GROUP BY "api_thread"."id"

我需要做什么才能将数字转换为布尔值。在 SQL 中看起来像

COUNT("api_thread_mark"."user_id") FILTER (WHERE "auth_user"."username" = 'gou') > 0 AS "is_marked"

【问题讨论】:

可以分享一下相关型号吗? 【参考方案1】:

这样的?

from django.db.models import Case, When, Value, BooleanField, Count, Q

is_marked__count = Count('mark', Q(mark__username='gou'))
is_marked_bool = Case(When(is_marked__count__gt=0, then=Value(True)), default=Value(False), output_field=BooleanField())

Thread.objects.all().annotate(is_marked__count=is_marked__count).annotate(is_marked_bool=is_marked_bool

参考:Conditional Expressions

【讨论】:

谢谢,伙计。但是你忘记了 output_field

以上是关于如何使用 Django ORM 将注释字符串转换为布尔值的主要内容,如果未能解决你的问题,请参考以下文章

复杂的 Django ORM 注释和聚合

如何使用注释在 Django ORM 中创建通知日期字段

使用Django ORM查询如何注释是不是存在多级外键层次结构

python Django - 将SQL查询转换为ORM查询

将 MySql 查询转换为 Django ORM 查询

Django ORM:如何根据注释 timedelta 结果进行过滤