[Django] #30052: QuerySet's `only()` method does not work with annotated fields

11 views
Skip to first unread message

Django

unread,
Dec 21, 2018, 3:06:47 AM12/21/18
to django-...@googlegroups.com
#30052: QuerySet's `only()` method does not work with annotated fields
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: | Status: new
Uncategorized |
Component: Database | Version: 2.1
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Example:


{{{
from django.db import models


class School(models.Model):
full_name = models.TextField()


class Student(models.Model):
full_name = models.TextField()
date_of_birth = models.DateField()
school = models.ForeignKey(School, on_delete=models.PROTECT)
}}}

And then:

{{{
from django.db.models import Subquery, OuterRef
from schools.models import School, Student

eldest_student_name =
Student.objects.filter(school=OuterRef('id')).order_by('date_of_birth').values('full_name')[:1]

schools =
School.objects.annotate(eldest_student_name=Subquery(eldest_student_name)).only('id',
'eldest_student_name')

for school in schools:
# This line results in FieldDoesNotExist: School has no field named
'eldest_student_name'
print(school.id, school.eldest_student_name)
}}}

Not sure if this is a bug or an (undocumented) limitation of `only()` (and
maybe of `defer()`, by extension).

--
Ticket URL: <https://code.djangoproject.com/ticket/30052>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 24, 2018, 10:59:03 AM12/24/18
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotatations

-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* status: new => closed
* type: Uncategorized => Bug
* resolution: => invalid


Comment:

As far as I tested, annotations don't need to be included in `only()` in
order to be included in the query. The documentation for `only()` and
`defer()` only discuss using it with fields, not with annotations.

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:1>

Django

unread,
Dec 24, 2018, 11:07:42 AM12/24/18
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations

-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:2>

Django

unread,
Jan 8, 2019, 3:13:51 AM1/8/19
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Kal Sze):

Replying to [comment:1 Tim Graham]:


> As far as I tested, annotations don't need to be included in `only()` in
order to be included in the query. The documentation for `only()` and
`defer()` only discuss using it with fields, not with annotations.

I know it doesn't need to be included, but I thought the point of `only()`
and `defer()` is to exclude the fields that we are not interested in, when
executing the initial database query. Having `only()` support annotations
is useful if I'm only interested in the annotated field, and not in the
regular fields.

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:3>

Django

unread,
Jan 8, 2019, 10:49:01 AM1/8/19
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

I'm not sure. Please test `only()` without arguments. If it works, it
might be worth adding tests for (if not already in Django's tests) and
documenting.

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:4>

Django

unread,
Jan 22, 2019, 1:52:13 AM1/22/19
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Kal Sze):

Replying to [comment:4 Tim Graham]:


> I'm not sure. Please test `only()` without arguments. If it works, it
might be worth adding tests for (if not already in Django's tests) and
documenting.

So I did a quick TIAS and here is what I found out, by printing
`QuerySet.query`:

- `QuerySet.only()` without any argument doesn't defer any field; it would
select every field of the model plus any annotation added to the QuerySet;
- `QuerySet.only('some_field')` would select the `id`, `some_field`, plus
any annotation added to the QuerySet.

Ideally, it would be great if `only()` behaved in one of two ways:
- without any argument, defer all fields except the id and annotations;
or
- accept annotated field names

But it might break old apps and it's too late to change.

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:5>

Django

unread,
Jul 20, 2023, 1:02:27 PM7/20/23
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by GitHub <noreply@…>):

In [changeset:"b126f694160c4641e64e57dba6b022f06fbfa745" b126f69]:
{{{
#!CommitTicketReference repository=""
revision="b126f694160c4641e64e57dba6b022f06fbfa745"
Refs #30052 -- Clarified that defer() and only() do not work with
aggregated fields.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:6>

Django

unread,
Jul 20, 2023, 1:08:07 PM7/20/23
to django-...@googlegroups.com
#30052: QuerySet.only() doesn't support annotations
-------------------------------------+-------------------------------------
Reporter: Kal Sze | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 2.1
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Natalia <124304+nessita@…>):

In [changeset:"da92a971a087bac653015c384300b968c20fca35" da92a971]:
{{{
#!CommitTicketReference repository=""
revision="da92a971a087bac653015c384300b968c20fca35"
[4.2.x] Refs #30052 -- Clarified that defer() and only() do not work with
aggregated fields.

Backport of b126f694160c4641e64e57dba6b022f06fbfa745 from main
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:7>

Reply all
Reply to author
Forward
0 new messages