Loading django/db/models/sql/compiler.py +2 −3 Original line number Diff line number Diff line Loading @@ -664,8 +664,7 @@ class SQLCompiler(object): # Use True here because we are looking at the _reverse_ side of # the relation, which is always nullable. new_nullable = True table = model._meta.db_table self.fill_related_selections(model._meta, table, cur_depth + 1, self.fill_related_selections(model._meta, alias, cur_depth + 1, next, restricted, new_nullable) def deferred_to_columns(self): Loading tests/queries/models.py +26 −0 Original line number Diff line number Diff line Loading @@ -501,3 +501,29 @@ class OrderItem(models.Model): def __str__(self): return '%s' % self.pk class BaseUser(models.Model): pass @python_2_unicode_compatible class Task(models.Model): title = models.CharField(max_length=10) owner = models.ForeignKey(BaseUser, related_name='owner') creator = models.ForeignKey(BaseUser, related_name='creator') def __str__(self): return self.title @python_2_unicode_compatible class Staff(models.Model): name = models.CharField(max_length=10) def __str__(self): return self.name @python_2_unicode_compatible class StaffUser(BaseUser): staff = models.OneToOneField(Staff, related_name='user') def __str__(self): return self.staff tests/queries/tests.py +21 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ from .models import ( OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject, ModelA, ModelB, ModelC, ModelD, Responsibility, Job, JobResponsibilities, BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book, MyObject, Order, OrderItem, SharedConnection) MyObject, Order, OrderItem, SharedConnection, Task, Staff, StaffUser) class BaseQuerysetTest(TestCase): def assertValueQuerysetEqual(self, qs, values): Loading Loading @@ -2992,3 +2992,23 @@ class Ticket14056Tests(TestCase): SharedConnection.objects.order_by('-pointera__connection', 'pk'), expected_ordering, lambda x: x ) class Ticket20955Tests(TestCase): def test_ticket_20955(self): jack = Staff.objects.create(name='jackstaff') jackstaff = StaffUser.objects.create(staff=jack) jill = Staff.objects.create(name='jillstaff') jillstaff = StaffUser.objects.create(staff=jill) task = Task.objects.create(creator=jackstaff, owner=jillstaff, title="task") task_get = Task.objects.get(pk=task.pk) # Load data so that assertNumQueries doesn't complain about the get # version's queries. task_get.creator.staffuser.staff task_get.owner.staffuser.staff task_select_related = Task.objects.select_related( 'creator__staffuser__staff', 'owner__staffuser__staff').get(pk=task.pk) with self.assertNumQueries(0): self.assertEqual(task_select_related.creator.staffuser.staff, task_get.creator.staffuser.staff) self.assertEqual(task_select_related.owner.staffuser.staff, task_get.owner.staffuser.staff) Loading
django/db/models/sql/compiler.py +2 −3 Original line number Diff line number Diff line Loading @@ -664,8 +664,7 @@ class SQLCompiler(object): # Use True here because we are looking at the _reverse_ side of # the relation, which is always nullable. new_nullable = True table = model._meta.db_table self.fill_related_selections(model._meta, table, cur_depth + 1, self.fill_related_selections(model._meta, alias, cur_depth + 1, next, restricted, new_nullable) def deferred_to_columns(self): Loading
tests/queries/models.py +26 −0 Original line number Diff line number Diff line Loading @@ -501,3 +501,29 @@ class OrderItem(models.Model): def __str__(self): return '%s' % self.pk class BaseUser(models.Model): pass @python_2_unicode_compatible class Task(models.Model): title = models.CharField(max_length=10) owner = models.ForeignKey(BaseUser, related_name='owner') creator = models.ForeignKey(BaseUser, related_name='creator') def __str__(self): return self.title @python_2_unicode_compatible class Staff(models.Model): name = models.CharField(max_length=10) def __str__(self): return self.name @python_2_unicode_compatible class StaffUser(BaseUser): staff = models.OneToOneField(Staff, related_name='user') def __str__(self): return self.staff
tests/queries/tests.py +21 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ from .models import ( OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject, ModelA, ModelB, ModelC, ModelD, Responsibility, Job, JobResponsibilities, BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book, MyObject, Order, OrderItem, SharedConnection) MyObject, Order, OrderItem, SharedConnection, Task, Staff, StaffUser) class BaseQuerysetTest(TestCase): def assertValueQuerysetEqual(self, qs, values): Loading Loading @@ -2992,3 +2992,23 @@ class Ticket14056Tests(TestCase): SharedConnection.objects.order_by('-pointera__connection', 'pk'), expected_ordering, lambda x: x ) class Ticket20955Tests(TestCase): def test_ticket_20955(self): jack = Staff.objects.create(name='jackstaff') jackstaff = StaffUser.objects.create(staff=jack) jill = Staff.objects.create(name='jillstaff') jillstaff = StaffUser.objects.create(staff=jill) task = Task.objects.create(creator=jackstaff, owner=jillstaff, title="task") task_get = Task.objects.get(pk=task.pk) # Load data so that assertNumQueries doesn't complain about the get # version's queries. task_get.creator.staffuser.staff task_get.owner.staffuser.staff task_select_related = Task.objects.select_related( 'creator__staffuser__staff', 'owner__staffuser__staff').get(pk=task.pk) with self.assertNumQueries(0): self.assertEqual(task_select_related.creator.staffuser.staff, task_get.creator.staffuser.staff) self.assertEqual(task_select_related.owner.staffuser.staff, task_get.owner.staffuser.staff)