1
0
mirror of https://github.com/django/django.git synced 2025-10-28 08:06:09 +00:00

Fixed #35972 -- Fixed lookup crashes after subquery annotations.

This commit is contained in:
Jacob Walls
2024-12-29 01:13:48 -08:00
committed by Sarah Boyce
parent 079d31e698
commit 8914f4703c
11 changed files with 128 additions and 23 deletions

View File

@@ -5,6 +5,7 @@ from datetime import date, datetime
from django.core.exceptions import FieldError
from django.db import connection, models
from django.db.models.fields.related_lookups import RelatedGreaterThan
from django.db.models.functions import Lower
from django.db.models.lookups import EndsWith, StartsWith
from django.test import SimpleTestCase, TestCase, override_settings
from django.test.utils import register_lookup
@@ -17,15 +18,15 @@ class Div3Lookup(models.Lookup):
lookup_name = "div3"
def as_sql(self, compiler, connection):
lhs, params = self.process_lhs(compiler, connection)
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params.extend(rhs_params)
params = (*lhs_params, *rhs_params)
return "(%s) %%%% 3 = %s" % (lhs, rhs), params
def as_oracle(self, compiler, connection):
lhs, params = self.process_lhs(compiler, connection)
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params.extend(rhs_params)
params = (*lhs_params, *rhs_params)
return "mod(%s, 3) = %s" % (lhs, rhs), params
@@ -249,6 +250,39 @@ class LookupTests(TestCase):
self.assertSequenceEqual(qs1, [a1])
self.assertSequenceEqual(qs2, [a1])
def test_custom_lookup_with_subquery(self):
class NotEqual(models.Lookup):
lookup_name = "ne"
def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
# Although combining via (*lhs_params, *rhs_params) would be
# more resilient, the "simple" way works too.
params = lhs_params + rhs_params
return "%s <> %s" % (lhs, rhs), params
author = Author.objects.create(name="Isabella")
with register_lookup(models.Field, NotEqual):
qs = Author.objects.annotate(
unknown_age=models.Subquery(
Author.objects.filter(age__isnull=True)
.order_by("name")
.values("name")[:1]
)
).filter(unknown_age__ne="Plato")
self.assertSequenceEqual(qs, [author])
qs = Author.objects.annotate(
unknown_age=Lower(
Author.objects.filter(age__isnull=True)
.order_by("name")
.values("name")[:1]
)
).filter(unknown_age__ne="plato")
self.assertSequenceEqual(qs, [author])
def test_custom_exact_lookup_none_rhs(self):
"""
__exact=None is transformed to __isnull=True if a custom lookup class