Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

annotate: whether a given value exists in m2m field

I have a query that retrieve an object like this:

{
    "id": 1,
    "tags": [1, 2, 3]
}

I want to check whether a given tag (say, 1) exists in the tags field of the object, and annotate the result of the check as a field of the object:

{
    "id": 1,
    "tagged": true
}

This is what I came up with

annotate(
    tagged=Exists(
        Articles.tag_set.through.objects.filter(
            article_id=OuterRef("pk"), tag_id=tag.id
        )
    )
)

Since the relation tags is already loaded by the primary query, having a secondary query seems redundant to me.

Is there an easier way to structure this query? Something close to the filter in lookup syntax.

like image 579
jc127 Avatar asked Oct 16 '22 08:10

jc127


1 Answers

Assuming tags is an ArrayField

    q = Article.objects.annotate(
        tagged=Exists(
            Article.objects.filter(id=OuterRef('id'), tags__contains=[1])
        )
    )
like image 177
Aprimus Avatar answered Oct 18 '22 23:10

Aprimus