How to convert with annotate String to Bool with Django ORM

Issue

My question is as follows. There is a request

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

in SQL it looks like this

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"

What do I need to do to turn a number into an boolean. In SQL it look like

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

Solution

Something like this?

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

Ref: Conditional Expressions

Answered By – JPG

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published