Opened 4 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#36155 closed Cleanup/optimization (fixed)

Improve error handling when complex annotations are not passed an alias

Reported by: Vinko Mlacic Owned by: Vinko Mlacic
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Vinko Mlacic Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Vinko Mlacic)

When complex annotations are not passed an alias, the default alias is usually used. If the annotate arg does not define the default alias, an error saying "Complex annotations require an alias" is raised.

This works fine with args that are subclasses of Aggregate subclass because the default_alias property on the Aggregate subclass raises that same TypeError.

However, when using expressions that are not Aggregate subclasses, this fails with an obscure message saying that default_alias is not a property on the expression object.

Code to reproduce:

models.py:

class Book(models.Model):
    name = models.CharField(max_length=255)

tests.py:

Book.objects.annotate(Value("title"))
Traceback (most recent call last):
  File "/usr/lib/python3.12/unittest/case.py", line 58, in testPartExecutor
    yield
  File "/usr/lib/python3.12/unittest/case.py", line 634, in run
    self._callTestMethod(testMethod)
  File "/usr/lib/python3.12/unittest/case.py", line 589, in _callTestMethod
    if method() is not None:
       ^^^^^^^^
  File "/home/vinko/projects/django/tests/annotations/tests.py", line 975, in test_complex_annotations_must_have_an_alias
    Book.objects.annotate(Value("title"))
  File "/home/vinko/projects/django/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vinko/projects/django/django/db/models/query.py", line 1631, in annotate
    return self._annotate(args, kwargs, select=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vinko/projects/django/django/db/models/query.py", line 1648, in _annotate
    if arg.default_alias in kwargs:
       ^^^^^^^^^^^^^^^^^
AttributeError: 'Value' object has no attribute 'default_alias'

Similar happens with other non Aggregate types like: F, Case - When, Subquery, Exists, ...

Change History (7)

comment:1 by Vinko Mlacic, 4 weeks ago

Description: modified (diff)

comment:2 by Vinko Mlacic, 4 weeks ago

Opened a PR with the changes here: https://github.com/django/django/pull/19113

comment:3 by Vinko Mlacic, 4 weeks ago

It seems like the unwanted behavior originated from ed0cbc8d8b314e3b4a0305d0be3cf366d8ee4a74

comment:4 by Sarah Boyce, 3 weeks ago

Triage Stage: UnreviewedAccepted

Thank you for the ticket and patch! Agree this needs better handling 👍

comment:5 by Sarah Boyce, 3 weeks ago

Triage Stage: AcceptedReady for checkin

comment:6 by Sarah Boyce <42296566+sarahboyce@…>, 3 weeks ago

Resolution: fixed
Status: assignedclosed

In c6ace89:

Fixed #36155 -- Improved error handling when annotate arguments require an alias.

Regression in ed0cbc8d8b314e3b4a0305d0be3cf366d8ee4a74.

comment:7 by Sarah Boyce <42296566+sarahboyce@…>, 3 weeks ago

In d567e3a:

[5.2.x] Fixed #36155 -- Improved error handling when annotate arguments require an alias.

Regression in ed0cbc8d8b314e3b4a0305d0be3cf366d8ee4a74.

Backport of c6ace896a2da73356f7c9a655bbe32a0e3ce0435 from main.

Note: See TracTickets for help on using tickets.
Back to Top