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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user