diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index d44a07a8e3..6a95d32259 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -627,6 +627,13 @@ class SQLCompiler(object): fields = self.query.select_fields + self.query.related_select_fields else: fields = self.query.model._meta.fields + # If the field was deferred, exclude it from being passed + # into `resolve_columns` because it wasn't selected. + only_load = self.deferred_to_columns() + if only_load: + db_table = self.query.model._meta.db_table + fields = [f for f in fields if db_table in only_load and + f.column in only_load[db_table]] row = self.resolve_columns(row, fields) if self.query.aggregate_select: diff --git a/tests/regressiontests/defer_regress/models.py b/tests/regressiontests/defer_regress/models.py index a1cd19788d..90d975d14b 100644 --- a/tests/regressiontests/defer_regress/models.py +++ b/tests/regressiontests/defer_regress/models.py @@ -31,6 +31,10 @@ class Leaf(models.Model): def __unicode__(self): return self.name +class ResolveThis(models.Model): + num = models.FloatField() + name = models.CharField(max_length=16) + __test__ = {"regression_tests": """ Deferred fields should really be deferred and not accidentally use the field's default value just because they aren't passed to __init__. diff --git a/tests/regressiontests/defer_regress/tests.py b/tests/regressiontests/defer_regress/tests.py new file mode 100644 index 0000000000..860c7f8e31 --- /dev/null +++ b/tests/regressiontests/defer_regress/tests.py @@ -0,0 +1,9 @@ +from django.test import TestCase +from models import ResolveThis + +class DeferRegressionTest(TestCase): + def test_resolve_columns(self): + rt = ResolveThis.objects.create(num=5.0, name='Foobar') + qs = ResolveThis.objects.defer('num') + self.assertEqual(1, qs.count()) + self.assertEqual('Foobar', qs[0].name)