mirror of
https://github.com/django/django.git
synced 2024-11-24 11:48:10 +01:00
Fixed #34803 -- Fixed queryset crash when filtering againts deeply nested OuterRef annotations.
Thanks Pierre-Nicolas Rigal for the report.
Regression in c67ea79aa9
.
This commit is contained in:
parent
9c68792843
commit
9cc0d7f7f8
1
AUTHORS
1
AUTHORS
@ -1033,6 +1033,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Will Ayd <william.ayd@icloud.com>
|
||||
William Schwartz <wkschwartz@gmail.com>
|
||||
Will Hardy <django@willhardy.com.au>
|
||||
Will Zhao <www.gnomeek@gmail.com>
|
||||
Wilson Miner <wminer@gmail.com>
|
||||
Wim Glenn <hey@wimglenn.com>
|
||||
wojtek
|
||||
|
@ -885,6 +885,7 @@ class ResolvedOuterRef(F):
|
||||
|
||||
class OuterRef(F):
|
||||
contains_aggregate = False
|
||||
contains_over_clause = False
|
||||
|
||||
def resolve_expression(self, *args, **kwargs):
|
||||
if isinstance(self.name, self.__class__):
|
||||
|
@ -21,3 +21,6 @@ Bugfixes
|
||||
* Fixed a regression in Django 4.2.2 that caused an unnecessary selection of a
|
||||
non-nullable ``ManyToManyField`` without a natural key during serialization
|
||||
(:ticket:`34779`).
|
||||
|
||||
* Fixed a regression in Django 4.2 that caused a crash of a queryset when
|
||||
filtering against deeply nested ``OuterRef()`` annotations (:ticket:`34803`).
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user