Fixed #27594 -- Fixed select_related() with reverse self-referential OneToOneField.

Fix definition of `klass_info['from_parent']`. The relationship between
two models shouldn't be considered as being from a parent class if the
model classes are the same.

Thanks Tim for the review.
This commit is contained in:
Daniel Hillier 2016-12-14 01:06:54 +11:00 committed by Tim Graham
parent fa596f82a6
commit 4a9f9cc521
3 changed files with 20 additions and 3 deletions

View File

@ -724,7 +724,7 @@ class SQLCompiler(object):
_, _, _, joins, _ = self.query.setup_joins([related_field_name], opts, root_alias)
alias = joins[-1]
from_parent = issubclass(model, opts.model)
from_parent = issubclass(model, opts.model) and model is not opts.model
klass_info = {
'model': model,
'field': f,

View File

@ -102,3 +102,12 @@ class Child3(Child2):
class Child4(Child1):
value4 = models.IntegerField()
class LinkedList(models.Model):
name = models.CharField(max_length=50)
previous_item = models.OneToOneField(
'self', models.CASCADE,
related_name="next_item", blank=True,
null=True,
)

View File

@ -6,8 +6,9 @@ from django.core.exceptions import FieldError
from django.test import TestCase
from .models import (
AdvancedUserStat, Child1, Child2, Child3, Child4, Image, Parent1, Parent2,
Product, StatDetails, User, UserProfile, UserStat, UserStatResult,
AdvancedUserStat, Child1, Child2, Child3, Child4, Image, LinkedList,
Parent1, Parent2, Product, StatDetails, User, UserProfile, UserStat,
UserStatResult,
)
@ -212,6 +213,13 @@ class ReverseSelectRelatedTestCase(TestCase):
with self.assertNumQueries(1):
self.assertEqual(p.child1.child4.name1, 'n1')
def test_self_relation(self):
item1 = LinkedList.objects.create(name='item1')
LinkedList.objects.create(name='item2', previous_item=item1)
with self.assertNumQueries(1):
item1_db = LinkedList.objects.select_related('next_item').get(name='item1')
self.assertEqual(item1_db.next_item.name, 'item2')
class ReverseSelectRelatedValidationTests(TestCase):
"""