From b6d3212190b114f1ef90d7ee9edcdae046432779 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Sat, 10 May 2014 16:39:20 +0200 Subject: [PATCH] [1.6.x] Fixed #22508 -- Avoided overwriting select_related. Previously, known related objects overwrote related objects loaded though select_related. This could cancel the effect of select_related when it was used over more than one level. Thanks boxm for the bug report and timo for bisecting the regression. Conflicts: tests/select_related_regress/tests.py Backport of f574220f from master --- django/db/models/query.py | 3 +++ tests/select_related_regress/tests.py | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/django/db/models/query.py b/django/db/models/query.py index 44047d4689..48a7ffbbf1 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -246,6 +246,9 @@ class QuerySet(object): # Add the known related objects to the model, if there are any if self._known_related_objects: for field, rel_objs in self._known_related_objects.items(): + # Avoid overwriting objects loaded e.g. by select_related + if hasattr(obj, field.get_cache_name()): + continue pk = getattr(obj, field.get_attname()) try: rel_obj = rel_objs[pk] diff --git a/tests/select_related_regress/tests.py b/tests/select_related_regress/tests.py index f6d21b2dd9..a05ec99074 100644 --- a/tests/select_related_regress/tests.py +++ b/tests/select_related_regress/tests.py @@ -173,3 +173,13 @@ class SelectRelatedRegressTests(TestCase): self.assertEqual(Chick.objects.all()[0].mother.name, 'Hen') self.assertEqual(Chick.objects.select_related()[0].mother.name, 'Hen') + + def test_regression_22508(self): + building = Building.objects.create(name='101') + device = Device.objects.create(name="router", building=building) + Port.objects.create(port_number='1', device=device) + + device = Device.objects.get() + port = device.port_set.select_related('device__building').get() + with self.assertNumQueries(0): + port.device.building