mirror of https://github.com/django/django.git
Fixed #17485 regression -- only + select_related interaction
When doing deeper than one level select_related() + only queries(), the
code introduced in b6c356b7bb
errored
incorrectly.
Thanks to mrmachine for report & test case.
This commit is contained in:
parent
935a8635c2
commit
f399a804c9
|
@ -609,8 +609,12 @@ class SQLCompiler(object):
|
|||
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
|
||||
|
|
|
@ -52,6 +52,9 @@ class SimpleItem(models.Model):
|
|||
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)
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.db.models.loading import cache
|
|||
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 @@ class DeferRegressionTest(TestCase):
|
|||
RelatedItem,
|
||||
ResolveThis,
|
||||
SimpleItem,
|
||||
SpecialFeature,
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -152,6 +153,7 @@ class DeferRegressionTest(TestCase):
|
|||
"RelatedItem_Deferred_item_id",
|
||||
"ResolveThis",
|
||||
"SimpleItem",
|
||||
"SpecialFeature",
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -197,6 +199,18 @@ class DeferRegressionTest(TestCase):
|
|||
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,
|
||||
|
|
Loading…
Reference in New Issue