diff options
| author | willzhao <gnomeek@outlook.com> | 2023-08-31 07:51:44 +0000 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-09-01 10:44:20 +0200 |
| commit | 9cc0d7f7f85cecc3ad15bbc471fe6a08e4f515b6 (patch) | |
| tree | b50db16197265db37269d94ec68d8690ff58c57d /tests | |
| parent | 9c6879284315d5119942355c340c3e48f6c65882 (diff) | |
Fixed #34803 -- Fixed queryset crash when filtering againts deeply nested OuterRef annotations.
Thanks Pierre-Nicolas Rigal for the report.
Regression in c67ea79aa981ae82595d89f8018a41fcd842e7c9.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/expressions/models.py | 4 | ||||
| -rw-r--r-- | tests/expressions/tests.py | 30 |
2 files changed, 34 insertions, 0 deletions
diff --git a/tests/expressions/models.py b/tests/expressions/models.py index 35985dc5f0..0a8a0a6584 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -8,6 +8,9 @@ from django.db import models class Manager(models.Model): name = models.CharField(max_length=50) + secretary = models.ForeignKey( + "Employee", models.CASCADE, null=True, related_name="managers" + ) class Employee(models.Model): @@ -15,6 +18,7 @@ class Employee(models.Model): lastname = models.CharField(max_length=50) salary = models.IntegerField(blank=True, null=True) manager = models.ForeignKey(Manager, models.CASCADE, null=True) + based_in_eu = models.BooleanField(default=False) def __str__(self): return "%s %s" % (self.firstname, self.lastname) diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 9ba354f9f4..4bd46762e1 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -870,6 +870,36 @@ class BasicExpressionsTests(TestCase): ).filter(ceo_company__isnull=False) self.assertEqual(qs.get().ceo_company, "Test GmbH") + def test_annotation_with_deeply_nested_outerref(self): + bob = Employee.objects.create(firstname="Bob", based_in_eu=True) + self.max.manager = Manager.objects.create(name="Rock", secretary=bob) + self.max.save() + qs = Employee.objects.filter( + Exists( + Manager.objects.filter( + Exists( + Employee.objects.filter( + pk=OuterRef("secretary__pk"), + ) + .annotate( + secretary_based_in_eu=OuterRef(OuterRef("based_in_eu")) + ) + .filter( + Exists( + Company.objects.filter( + # Inner OuterRef refers to an outer + # OuterRef (not ResolvedOuterRef). + based_in_eu=OuterRef("secretary_based_in_eu") + ) + ) + ) + ), + secretary__pk=OuterRef("pk"), + ) + ) + ) + self.assertEqual(qs.get(), bob) + def test_pickle_expression(self): expr = Value(1) expr.convert_value # populate cached property |
