From c9fd9ffd9b0e713ef3aa5061c36d8aed52420c7c Mon Sep 17 00:00:00 2001 From: Arpit Date: Sun, 28 May 2023 10:51:09 +0530 Subject: [PATCH] Added support to fetch latest object from mongoengine queryset Update tests Handle comment to address the incosistent behaviour --- mongoengine/queryset/base.py | 17 +++++++++++++++++ tests/queryset/test_queryset.py | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index d33e7b1e3..a78dd52c6 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -298,6 +298,23 @@ def first(self): result = None return result + def last(self): + """Retrieve the latest object matching the query.""" + if not self._ordering: + raise OperationError( + "Cannot use `last()` without ordering. Use `order_by()` on the queryset first." + ) + + queryset = self.clone() + if self._none or self._empty: + return None + + try: + result = queryset[self.count() - 1] + except IndexError: + result = None + return result + def insert( self, doc_or_docs, load_bulk=True, write_concern=None, signal_kwargs=None ): diff --git a/tests/queryset/test_queryset.py b/tests/queryset/test_queryset.py index d1cae3415..7eb094269 100644 --- a/tests/queryset/test_queryset.py +++ b/tests/queryset/test_queryset.py @@ -2599,6 +2599,32 @@ def test_order_by(self): ages = [p.age for p in self.Person.objects.order_by("")] assert ages == [40, 20, 30] + def test_last(self): + """Ensure the retrieval of the latest object from the QuerySet based on the specified ordering.""" + person1 = self.Person(name="User B", age=40).save() + person2 = self.Person(name="User A", age=20).save() + person3 = self.Person(name="User C", age=30).save() + + assert self.Person.objects.order_by("age").last() == person1 + assert self.Person.objects.order_by("-age").last() == person2 + + person2.age = 31 + person2.save() + assert self.Person.objects.order_by("-age").last() == person3 + assert self.Person.objects.order_by("age").last() == person1 + + person1.age = 41 + person1.save() + assert self.Person.objects.order_by("age").last() == person1 + + assert self.Person.objects.order_by("name").last() == person3 + + assert self.Person.objects.filter(age__lt=40).order_by("age").last() == person2 + assert self.Person.objects.filter(age__gt=50).order_by("age").last() is None + + with pytest.raises(OperationError): + self.Person.objects.last() + def test_order_by_optional(self): class BlogPost(Document): title = StringField()