mirror of
https://github.com/django/django.git
synced 2025-10-23 21:59:11 +00:00
[6.0.x] Fixed #36648, Refs #33772 -- Accounted for composite pks in first()/last() when aggregating.
Backport of 02eed4f378
from main.
This commit is contained in:
@@ -2077,8 +2077,14 @@ class QuerySet(AltersData):
|
|||||||
raise TypeError(f"Cannot use {operator_} operator with combined queryset.")
|
raise TypeError(f"Cannot use {operator_} operator with combined queryset.")
|
||||||
|
|
||||||
def _check_ordering_first_last_queryset_aggregation(self, method):
|
def _check_ordering_first_last_queryset_aggregation(self, method):
|
||||||
if isinstance(self.query.group_by, tuple) and not any(
|
if (
|
||||||
col.output_field is self.model._meta.pk for col in self.query.group_by
|
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(
|
raise TypeError(
|
||||||
f"Cannot use QuerySet.{method}() on an unordered queryset performing "
|
f"Cannot use QuerySet.{method}() on an unordered queryset performing "
|
||||||
|
@@ -10,3 +10,7 @@ Bugfixes
|
|||||||
========
|
========
|
||||||
|
|
||||||
* Added compatibility for ``oracledb`` 3.4.0 (:ticket:`36646`).
|
* 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.
|
||||||
|
@@ -141,3 +141,23 @@ class CompositePKAggregateTests(TestCase):
|
|||||||
msg = "Max expression does not support composite primary keys."
|
msg = "Max expression does not support composite primary keys."
|
||||||
with self.assertRaisesMessage(ValueError, msg):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
Comment.objects.aggregate(Max("pk"))
|
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()
|
||||||
|
Reference in New Issue
Block a user