Fixed #16409 -- Fixed an error condition when using QuerySet only()/defer() on the result of an annotate() call. Thanks jaklaassen AT gmail DOT com and Tai Lee for the reports and Tai for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16522 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Ramiro Morales 2011-07-07 01:12:45 +00:00
parent f5c9c2246e
commit b2050ff546
3 changed files with 9 additions and 4 deletions

View File

@ -231,9 +231,6 @@ class QuerySet(object):
fields = self.model._meta.fields fields = self.model._meta.fields
pk_idx = self.model._meta.pk_index() pk_idx = self.model._meta.pk_index()
index_start = len(extra_select)
aggregate_start = index_start + len(self.model._meta.fields)
load_fields = [] load_fields = []
# If only/defer clauses have been specified, # If only/defer clauses have been specified,
# build the list of fields that are to be loaded. # build the list of fields that are to be loaded.
@ -253,6 +250,9 @@ class QuerySet(object):
# Therefore, we need to load all fields from this model # Therefore, we need to load all fields from this model
load_fields.append(field.name) load_fields.append(field.name)
index_start = len(extra_select)
aggregate_start = index_start + len(load_fields or self.model._meta.fields)
skip = None skip = None
if load_fields and not fill_cache: if load_fields and not fill_cache:
# Some fields have been deferred, so we have to initialise # Some fields have been deferred, so we have to initialise

View File

@ -169,7 +169,7 @@ class SQLCompiler(object):
if isinstance(col, (list, tuple)): if isinstance(col, (list, tuple)):
alias, column = col alias, column = col
table = self.query.alias_map[alias][TABLE_NAME] table = self.query.alias_map[alias][TABLE_NAME]
if table in only_load and col not in only_load[table]: if table in only_load and column not in only_load[table]:
continue continue
r = '%s.%s' % (qn(alias), qn(column)) r = '%s.%s' % (qn(alias), qn(column))
if with_aliases: if with_aliases:

View File

@ -4,6 +4,7 @@ from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.backends.db import SessionStore from django.contrib.sessions.backends.db import SessionStore
from django.db import connection from django.db import connection
from django.db.models import Count
from django.db.models.loading import cache from django.db.models.loading import cache
from django.test import TestCase from django.test import TestCase
@ -148,6 +149,10 @@ class DeferRegressionTest(TestCase):
] ]
) )
# Regression for #16409 - make sure defer() and only() work with annotate()
self.assertIsInstance(list(Item.objects.annotate(Count('relateditem')).defer('name')), list)
self.assertIsInstance(list(Item.objects.annotate(Count('relateditem')).only('name')), list)
def test_only_and_defer_usage_on_proxy_models(self): def test_only_and_defer_usage_on_proxy_models(self):
# Regression for #15790 - only() broken for proxy models # Regression for #15790 - only() broken for proxy models
proxy = Proxy.objects.create(name="proxy", value=42) proxy = Proxy.objects.create(name="proxy", value=42)