mirror of
https://github.com/django/django.git
synced 2025-03-06 15:32:33 +00:00
[5.2.x] Fixed #36155 -- Improved error handling when annotate arguments require an alias.
Regression in ed0cbc8d8b314e3b4a0305d0be3cf366d8ee4a74. Backport of c6ace896a2da73356f7c9a655bbe32a0e3ce0435 from main.
This commit is contained in:
parent
dfaf8aa6c6
commit
d567e3a52e
1
AUTHORS
1
AUTHORS
@ -1053,6 +1053,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Vinay Karanam <https://github.com/vinayinvicible>
|
Vinay Karanam <https://github.com/vinayinvicible>
|
||||||
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
||||||
Vincent Foley <vfoleybourgon@yahoo.ca>
|
Vincent Foley <vfoleybourgon@yahoo.ca>
|
||||||
|
Vinko Mlačić <vinkomlacic@outlook.com>
|
||||||
Vinny Do <vdo.code@gmail.com>
|
Vinny Do <vdo.code@gmail.com>
|
||||||
Vitaly Babiy <vbabiy86@gmail.com>
|
Vitaly Babiy <vbabiy86@gmail.com>
|
||||||
Vitaliy Yelnik <velnik@gmail.com>
|
Vitaliy Yelnik <velnik@gmail.com>
|
||||||
|
@ -1647,14 +1647,16 @@ class QuerySet(AltersData):
|
|||||||
)
|
)
|
||||||
annotations = {}
|
annotations = {}
|
||||||
for arg in args:
|
for arg in args:
|
||||||
# The default_alias property may raise a TypeError.
|
# The default_alias property raises TypeError if default_alias
|
||||||
|
# can't be set automatically or AttributeError if it isn't an
|
||||||
|
# attribute.
|
||||||
try:
|
try:
|
||||||
if arg.default_alias in kwargs:
|
if arg.default_alias in kwargs:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"The named annotation '%s' conflicts with the "
|
"The named annotation '%s' conflicts with the "
|
||||||
"default name for another annotation." % arg.default_alias
|
"default name for another annotation." % arg.default_alias
|
||||||
)
|
)
|
||||||
except TypeError:
|
except (TypeError, AttributeError):
|
||||||
raise TypeError("Complex annotations require an alias")
|
raise TypeError("Complex annotations require an alias")
|
||||||
annotations[arg.default_alias] = arg
|
annotations[arg.default_alias] = arg
|
||||||
annotations.update(kwargs)
|
annotations.update(kwargs)
|
||||||
|
@ -969,6 +969,24 @@ class NonAggregateAnnotationTestCase(TestCase):
|
|||||||
):
|
):
|
||||||
Book.objects.annotate(BooleanField(), Value(False), is_book=True)
|
Book.objects.annotate(BooleanField(), Value(False), is_book=True)
|
||||||
|
|
||||||
|
def test_complex_annotations_must_have_an_alias(self):
|
||||||
|
complex_annotations = [
|
||||||
|
F("rating") * F("price"),
|
||||||
|
Value("title"),
|
||||||
|
Case(When(pages__gte=400, then=Value("Long")), default=Value("Short")),
|
||||||
|
Subquery(
|
||||||
|
Book.objects.filter(publisher_id=OuterRef("pk"))
|
||||||
|
.order_by("-pubdate")
|
||||||
|
.values("name")[:1]
|
||||||
|
),
|
||||||
|
Exists(Book.objects.filter(publisher_id=OuterRef("pk"))),
|
||||||
|
]
|
||||||
|
msg = "Complex annotations require an alias"
|
||||||
|
for annotation in complex_annotations:
|
||||||
|
with self.subTest(annotation=annotation):
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
Book.objects.annotate(annotation)
|
||||||
|
|
||||||
def test_chaining_annotation_filter_with_m2m(self):
|
def test_chaining_annotation_filter_with_m2m(self):
|
||||||
qs = (
|
qs = (
|
||||||
Author.objects.filter(
|
Author.objects.filter(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user