#37312 new Bug

QuerySet.in_bulk() drops annotations selected by values() and values_list().

Reported by: Yassin Bahri Owned by:
Component: Database layer (models, ORM) Version: 6.1
Severity: Normal Keywords: in_bulk values annotations
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

QuerySet.in_bulk() silently drops annotations selected by .values() or .values_list() when the field used as the dictionary key isn't included in the selected fields.

This is reproducible on current main at 5babd2e21ac0877d66c5452da17b97608b337fba and on stable/6.1.x at 4b0185a5fb, using SQLite.

Given these models:

class Author(models.Model):
    name = models.CharField(max_length=100)


class Article(models.Model):
    headline = models.CharField(max_length=100)
    author = models.ForeignKey(Author, models.CASCADE)

The following reproduces the issue:

from django.db.models import F

author = Author.objects.create(name="Author 1")
article = Article.objects.create(
    headline="Article 1",
    author=author,
)

result = (
    Article.objects.annotate(author_name=F("author__name"))
    .values("headline", "author_name")
    .in_bulk([article.pk])
)

print(result)

The actual result omits the selected annotation:

{
    article.pk: {
        "headline": "Article 1",
    }
}

The expected result is:

{
    article.pk: {
        "headline": "Article 1",
        "author_name": "Author 1",
    }
}

The same problem occurs with .values_list():

result = (
    Article.objects.annotate(author_name=F("author__name"))
    .values_list("headline", "author_name")
    .in_bulk([article.pk])
)

The actual value is:

{article.pk: ("Article 1",)}

instead of:

{article.pk: ("Article 1", "Author 1")}

Support for chaining in_bulk() after values() and values_list() was added in #36605 by 1820d35.

When in_bulk() internally adds the missing key field to the projection, it rebuilds the projection from query.values_select. Selected annotations are stored separately and are therefore omitted from the rebuilt projection.

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top