[1.6.x] Fixed #21150 -- Improved Query.add_fields() join promotion logic
Thanks to Eivind Fonn for the report and test case.
This commit is contained in:
parent
d30d66b907
commit
1a922870ea
|
@ -1525,7 +1525,7 @@ class Query(object):
|
||||||
for name in field_names:
|
for name in field_names:
|
||||||
field, targets, u2, joins, path = self.setup_joins(
|
field, targets, u2, joins, path = self.setup_joins(
|
||||||
name.split(LOOKUP_SEP), opts, alias, None, allow_m2m,
|
name.split(LOOKUP_SEP), opts, alias, None, allow_m2m,
|
||||||
True)
|
allow_explicit_fk=True, outer_if_first=True)
|
||||||
|
|
||||||
# Trim last join if possible
|
# Trim last join if possible
|
||||||
targets, final_alias, remaining_joins = self.trim_joins(targets, joins[-2:], path)
|
targets, final_alias, remaining_joins = self.trim_joins(targets, joins[-2:], path)
|
||||||
|
|
|
@ -87,3 +87,14 @@ class HardbackBook(Book):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (hardback): %s" % (self.name, self.weight)
|
return "%s (hardback): %s" % (self.name, self.weight)
|
||||||
|
|
||||||
|
# Models for ticket #21150
|
||||||
|
class Alfa(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Bravo(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Charlie(models.Model):
|
||||||
|
alfa = models.ForeignKey(Alfa, null=True)
|
||||||
|
bravo = models.ForeignKey(Bravo, null=True)
|
||||||
|
|
|
@ -12,8 +12,9 @@ from django.test import TestCase, Approximate, skipUnlessDBFeature
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.unittest import expectedFailure
|
from django.utils.unittest import expectedFailure
|
||||||
|
|
||||||
from .models import (Author, Book, Publisher, Clues, Entries, HardbackBook,
|
from .models import (
|
||||||
ItemTag, WithManualPK)
|
Author, Book, Publisher, Clues, Entries, HardbackBook, ItemTag,
|
||||||
|
WithManualPK, Alfa, Bravo, Charlie)
|
||||||
|
|
||||||
|
|
||||||
class AggregationTests(TestCase):
|
class AggregationTests(TestCase):
|
||||||
|
@ -1107,3 +1108,19 @@ class AggregationTests(TestCase):
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
qs, ['Sams Teach Yourself Django in 24 Hours'],
|
qs, ['Sams Teach Yourself Django in 24 Hours'],
|
||||||
lambda b: b.name)
|
lambda b: b.name)
|
||||||
|
|
||||||
|
def test_ticket_21150(self):
|
||||||
|
b = Bravo.objects.create()
|
||||||
|
c = Charlie.objects.create(bravo=b)
|
||||||
|
qs = Charlie.objects.select_related('alfa').annotate(Count('bravo__charlie'))
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
qs, [c], lambda x: x)
|
||||||
|
self.assertIs(qs[0].alfa, None)
|
||||||
|
a = Alfa.objects.create()
|
||||||
|
c.alfa = a
|
||||||
|
c.save()
|
||||||
|
# Force re-evaluation
|
||||||
|
qs = qs.all()
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
qs, [c], lambda x: x)
|
||||||
|
self.assertEqual(qs[0].alfa, a)
|
||||||
|
|
Loading…
Reference in New Issue