Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #17485 regression -- only + select_related interaction

When doing deeper than one level select_related() + only queries(), the
code introduced in b6c356b errored
incorrectly.

Thanks to mrmachine for report & test case.
  • Loading branch information...
commit f399a804c9436a5d3ef9e2b73c337904af2c753d 1 parent 935a863
Anssi Kääriäinen akaariai authored
6 django/db/models/sql/compiler.py
View
@@ -609,8 +609,12 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
restricted = False
for f, model in opts.get_fields_with_model():
+ # The get_fields_with_model() returns None for fields that live
+ # in the field's local model. So, for those fields we want to use
+ # the f.model - that is the field's local model.
+ field_model = model or f.model
if not select_related_descend(f, restricted, requested,
- only_load.get(model or self.query.model)):
+ only_load.get(field_model)):
continue
# The "avoid" set is aliases we want to avoid just for this
# particular branch of the recursion. They aren't permanently
3  tests/regressiontests/defer_regress/models.py
View
@@ -52,6 +52,9 @@ def __str__(self):
class Feature(models.Model):
item = models.ForeignKey(SimpleItem)
+class SpecialFeature(models.Model):
+ feature = models.ForeignKey(Feature)
+
class ItemAndSimpleItem(models.Model):
item = models.ForeignKey(Item)
simple = models.ForeignKey(SimpleItem)
16 tests/regressiontests/defer_regress/tests.py
View
@@ -9,7 +9,7 @@
from django.test import TestCase
from .models import (ResolveThis, Item, RelatedItem, Child, Leaf, Proxy,
- SimpleItem, Feature, ItemAndSimpleItem)
+ SimpleItem, Feature, ItemAndSimpleItem, SpecialFeature)
class DeferRegressionTest(TestCase):
@@ -115,6 +115,7 @@ def test_basic(self):
RelatedItem,
ResolveThis,
SimpleItem,
+ SpecialFeature,
]
)
@@ -152,6 +153,7 @@ def test_basic(self):
"RelatedItem_Deferred_item_id",
"ResolveThis",
"SimpleItem",
+ "SpecialFeature",
]
)
@@ -197,6 +199,18 @@ def test_defer_with_select_related(self):
self.assertEqual(obj.item, item2)
self.assertEqual(obj.item_id, item2.id)
+ def test_only_with_select_related(self):
+ # Test for #17485.
+ item = SimpleItem.objects.create(name='first', value=47)
+ feature = Feature.objects.create(item=item)
+ SpecialFeature.objects.create(feature=feature)
+
+ qs = Feature.objects.only('item__name').select_related('item')
+ self.assertEqual(len(qs), 1)
+
+ qs = SpecialFeature.objects.only('feature__item__name').select_related('feature__item')
+ self.assertEqual(len(qs), 1)
+
def test_deferred_class_factory(self):
from django.db.models.query_utils import deferred_class_factory
new_class = deferred_class_factory(Item,
Please sign in to comment.
Something went wrong with that request. Please try again.