diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index ab249e50a08..50034bc3690 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -775,7 +775,8 @@ class SQLCompiler(object): for rows in self.execute_sql(MULTI): for row in rows: if has_aggregate_select: - aggregate_start = len(self.query.extra_select) + len(self.query.select) + loaded_fields = self.query.get_loaded_field_names().get(self.query.model, set()) or self.query.select + aggregate_start = len(self.query.extra_select) + len(loaded_fields) aggregate_end = aggregate_start + len(self.query.aggregate_select) if resolve_columns: if fields is None: diff --git a/tests/modeltests/defer/models.py b/tests/modeltests/defer/models.py index 0688cbc9840..f42f865362b 100644 --- a/tests/modeltests/defer/models.py +++ b/tests/modeltests/defer/models.py @@ -28,3 +28,22 @@ class BigChild(Primary): class ChildProxy(Child): class Meta: proxy=True + +class Profile(models.Model): + profile1 = models.TextField(default='profile1') + +class Location(models.Model): + location1 = models.TextField(default='location1') + +class Item(models.Model): + pass + +class Request(models.Model): + profile = models.ForeignKey(Profile, null=True, blank=True) + location = models.ForeignKey(Location) + items = models.ManyToManyField(Item) + + request1 = models.TextField(default='request1') + request2 = models.TextField(default='request2') + request3 = models.TextField(default='request3') + request4 = models.TextField(default='request4') diff --git a/tests/modeltests/defer/tests.py b/tests/modeltests/defer/tests.py index 50db5a76b40..f0270479d46 100644 --- a/tests/modeltests/defer/tests.py +++ b/tests/modeltests/defer/tests.py @@ -1,9 +1,10 @@ from __future__ import absolute_import +from django.db.models import Count from django.db.models.query_utils import DeferredAttribute, InvalidQuery from django.test import TestCase -from .models import Secondary, Primary, Child, BigChild, ChildProxy +from .models import Secondary, Primary, Child, BigChild, ChildProxy, Location, Request class DeferTests(TestCase): @@ -183,3 +184,17 @@ class DeferTests(TestCase): with self.assertNumQueries(0): bc_deferred.id self.assertEqual(bc_deferred.pk, bc_deferred.id) + +class DeferAnnotateSelectRelatedTest(TestCase): + def test_defer_annotate_select_related(self): + location = Location.objects.create() + Request.objects.create(location=location) + self.assertIsInstance(list(Request.objects + .annotate(Count('items')).select_related('profile', 'location') + .only('profile', 'location')), list) + self.assertIsInstance(list(Request.objects + .annotate(Count('items')).select_related('profile', 'location') + .only('profile__profile1', 'location__location1')), list) + self.assertIsInstance(list(Request.objects + .annotate(Count('items')).select_related('profile', 'location') + .defer('request1', 'request2', 'request3', 'request4')), list)