From: Jeremy Kerr <jk@ozlabs.org>
Date: Thu, 31 Aug 2017 08:59:45 +0800
Subject: Fix QuerySet.defer() with super and subclass fields.

Fixed #28549 -- Fixed QuerySet.defer() with super and subclass fields.

commit 84b7cb7df00192b2f804e2c6fd98b78b5bfd1ffa upstream.

Previously, deferring fields in different classes didn't omit the
superclass' deferred field.

Thanks Simon Charette for the suggested fix.

[ajd: backported on top of Debian tree]
Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
---
 django/db/models/sql/query.py | 2 +-
 tests/defer/tests.py          | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index e51b103..8813dce 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -669,7 +669,7 @@ class Query(object):
             # models.
             workset = {}
             for model, values in six.iteritems(seen):
-                for field in model._meta.fields:
+                for field in model._meta.local_fields:
                     if field in values:
                         continue
                     m = field.model._meta.concrete_model
diff --git a/tests/defer/tests.py b/tests/defer/tests.py
index 65f1f2b..ef7180a 100644
--- a/tests/defer/tests.py
+++ b/tests/defer/tests.py
@@ -190,6 +190,11 @@ class BigChildDeferTests(AssertionMixin, TestCase):
         self.assertEqual(obj.value, "foo")
         self.assertEqual(obj.other, "bar")
 
+    def test_defer_subclass_both(self):
+        # Deferring fields from both superclass and subclass works.
+        obj = BigChild.objects.defer("other", "value").get(name="b1")
+        self.assert_delayed(obj, 2)
+
     def test_only_baseclass_when_subclass_has_added_field(self):
         # You can retrieve a single field on a baseclass
         obj = BigChild.objects.only("name").get(name="b1")
