Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions django/db/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -2141,8 +2141,14 @@ def _check_operator_queryset(self, other, operator_):
raise TypeError(f"Cannot use {operator_} operator with combined queryset.")

def _check_ordering_first_last_queryset_aggregation(self, method):
if isinstance(self.query.group_by, tuple) and not any(
col.output_field is self.model._meta.pk for col in self.query.group_by
if (
isinstance(self.query.group_by, tuple)
# Raise if the pk fields are not in the group_by.
and self.model._meta.pk
not in {col.output_field for col in self.query.group_by}
and set(self.model._meta.pk_fields).difference(
{col.target for col in self.query.group_by}
)
):
raise TypeError(
f"Cannot use QuerySet.{method}() on an unordered queryset performing "
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/5.2.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ Bugfixes
========

* Added compatibility for ``oracledb`` 3.4.0 (:ticket:`36646`).

* Fixed a bug in Django 5.2 where ``QuerySet.first()`` and ``QuerySet.last()``
raised an error on querysets performing aggregation that selected all fields
of a composite primary key.
20 changes: 20 additions & 0 deletions tests/composite_pk/test_aggregate.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,23 @@ def test_max_pk(self):
msg = "Max expression does not support composite primary keys."
with self.assertRaisesMessage(ValueError, msg):
Comment.objects.aggregate(Max("pk"))

def test_first_from_unordered_queryset_aggregation_pk_selected(self):
self.assertEqual(
Comment.objects.values("pk").annotate(max=Max("id")).first(),
{"pk": (1, 1), "max": 1},
)

def test_first_from_unordered_queryset_aggregation_pk_selected_separately(self):
self.assertEqual(
Comment.objects.values("tenant", "id").annotate(max=Max("id")).first(),
{"tenant": 1, "id": 1, "max": 1},
)

def test_first_from_unordered_queryset_aggregation_pk_incomplete(self):
msg = (
"Cannot use QuerySet.first() on an unordered queryset performing "
"aggregation. Add an ordering with order_by()."
)
with self.assertRaisesMessage(TypeError, msg):
Comment.objects.values("tenant").annotate(max=Max("id")).first()
Loading