diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index adafd26e89..2db832e1eb 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -939,7 +939,7 @@ class Subquery(Expression): ) # Add table alias to the parent query's aliases to prevent # quoting. - if hasattr(resolved, 'alias'): + if hasattr(resolved, 'alias') and resolved.alias != resolved.target.model._meta.db_table: clone.queryset.query.external_aliases.add(resolved.alias) return resolved return child diff --git a/docs/releases/1.11.7.txt b/docs/releases/1.11.7.txt index fe2cf2e300..81334533e9 100644 --- a/docs/releases/1.11.7.txt +++ b/docs/releases/1.11.7.txt @@ -16,3 +16,6 @@ Bugfixes * Made ``QuerySet.reverse()`` affect ``nulls_first`` and ``nulls_last`` (:ticket:`28722`). + +* Fixed unquoted table names in ``Subquery`` SQL when using ``OuterRef`` + (:ticket:`28689`). diff --git a/tests/expressions/models.py b/tests/expressions/models.py index b1a737d0b9..678af731f8 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -56,6 +56,7 @@ class Experiment(models.Model): end = models.DateTimeField() class Meta: + db_table = 'expressions_ExPeRiMeNt' ordering = ('name',) def duration(self): diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 253a9c0429..17d4ec4e7b 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -533,6 +533,11 @@ class BasicExpressionsTests(TestCase): outer = Company.objects.filter(pk__in=Subquery(inner.values('pk'))) self.assertFalse(outer.exists()) + def test_outerref_mixed_case_table_name(self): + inner = Result.objects.filter(result_time__gte=OuterRef('experiment__assigned')) + outer = Result.objects.filter(pk__in=Subquery(inner.values('pk'))) + self.assertFalse(outer.exists()) + class IterableLookupInnerExpressionsTests(TestCase): @classmethod