diff options
| author | willzhao <gnomeek@outlook.com> | 2023-08-31 07:51:44 +0000 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-09-01 11:25:00 +0200 |
| commit | acfb42752259c3f920ffd20d6eef83b3c6f75cf7 (patch) | |
| tree | 552ba3871fcacd330d58a91c91a17fddaa85bf46 /tests | |
| parent | 55a0b9c32ebae957b95a9a55846692837e2ff39b (diff) | |
[4.2.x] Fixed #34803 -- Fixed queryset crash when filtering againts deeply nested OuterRef annotations.
Thanks Pierre-Nicolas Rigal for the report.
Regression in c67ea79aa981ae82595d89f8018a41fcd842e7c9.
Backport of 9cc0d7f7f85cecc3ad15bbc471fe6a08e4f515b6 from main
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 7db6013819..a928b76bab 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -871,6 +871,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 |
