#37312: QuerySet.in_bulk() drops annotations selected by values() and
values_list().
-------------------------------------+-------------------------------------
Reporter: Yassin Bahri | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 6.1 | Severity: Normal
Keywords: in_bulk values | Triage Stage:
annotations | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
`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:
{{{#!python
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:
{{{#!python
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:
{{{#!python
{
article.pk: {
"headline": "Article 1",
}
}
}}}
The expected result is:
{{{#!python
{
article.pk: {
"headline": "Article 1",
"author_name": "Author 1",
}
}
}}}
The same problem occurs with `.values_list()`:
{{{#!python
result = (
Article.objects.annotate(author_name=F("author__name"))
.values_list("headline", "author_name")
.in_bulk([
article.pk])
)
}}}
The actual value is:
{{{#!python
{
article.pk: ("Article 1",)}
}}}
instead of:
{{{#!python
{
article.pk: ("Article 1", "Author 1")}
}}}
Support for chaining `in_bulk()` after `values()` and `values_list()` was
added in #36605 by [
https://github.com/django/django/commit/1820d35b17f
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.
--
Ticket URL: <
https://code.djangoproject.com/ticket/37312>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.