1
0
mirror of https://github.com/django/django.git synced 2025-10-29 16:46:11 +00:00

Fixed #33772 -- Added QuerySet.first()/last() error message on unordered queryset with aggregation.

This commit is contained in:
Pablo Pissi
2022-06-12 22:08:21 -03:00
committed by Mariusz Felisiak
parent db588d4f0e
commit d287294885
4 changed files with 47 additions and 3 deletions

View File

@@ -1032,7 +1032,12 @@ class QuerySet:
def first(self):
"""Return the first object of a query or None if no match is found."""
for obj in (self if self.ordered else self.order_by("pk"))[:1]:
if self.ordered:
queryset = self
else:
self._check_ordering_first_last_queryset_aggregation(method="first")
queryset = self.order_by("pk")
for obj in queryset[:1]:
return obj
async def afirst(self):
@@ -1040,7 +1045,12 @@ class QuerySet:
def last(self):
"""Return the last object of a query or None if no match is found."""
for obj in (self.reverse() if self.ordered else self.order_by("-pk"))[:1]:
if self.ordered:
queryset = self.reverse()
else:
self._check_ordering_first_last_queryset_aggregation(method="last")
queryset = self.order_by("-pk")
for obj in queryset[:1]:
return obj
async def alast(self):
@@ -1926,6 +1936,15 @@ class QuerySet:
if self.query.combinator or other.query.combinator:
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
):
raise TypeError(
f"Cannot use QuerySet.{method}() on an unordered queryset performing "
f"aggregation. Add an ordering with order_by()."
)
class InstanceCheckMeta(type):
def __instancecheck__(self, instance):