{{{
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.
* 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>
--
Ticket URL: <https://code.djangoproject.com/ticket/30052#comment:2>
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>
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>
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>
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>
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>