mirror of https://github.com/django/django.git
Fixed #19326 -- Added first() and last() methods to QuerySet
This commit is contained in:
parent
d595b61aca
commit
ea9a0857d4
|
@ -186,6 +186,12 @@ class Manager(six.with_metaclass(RenameManagerMethods)):
|
||||||
def latest(self, *args, **kwargs):
|
def latest(self, *args, **kwargs):
|
||||||
return self.get_queryset().latest(*args, **kwargs)
|
return self.get_queryset().latest(*args, **kwargs)
|
||||||
|
|
||||||
|
def first(self):
|
||||||
|
return self.get_queryset().first()
|
||||||
|
|
||||||
|
def last(self):
|
||||||
|
return self.get_queryset().last()
|
||||||
|
|
||||||
def order_by(self, *args, **kwargs):
|
def order_by(self, *args, **kwargs):
|
||||||
return self.get_queryset().order_by(*args, **kwargs)
|
return self.get_queryset().order_by(*args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -498,6 +498,26 @@ class QuerySet(object):
|
||||||
def latest(self, field_name=None):
|
def latest(self, field_name=None):
|
||||||
return self._earliest_or_latest(field_name=field_name, direction="-")
|
return self._earliest_or_latest(field_name=field_name, direction="-")
|
||||||
|
|
||||||
|
def first(self):
|
||||||
|
"""
|
||||||
|
Returns the first object of a query, returns None if no match is found.
|
||||||
|
"""
|
||||||
|
qs = self if self.ordered else self.order_by('pk')
|
||||||
|
try:
|
||||||
|
return qs[0]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def last(self):
|
||||||
|
"""
|
||||||
|
Returns the last object of a query, returns None if no match is found.
|
||||||
|
"""
|
||||||
|
qs = self.reverse() if self.ordered else self.order_by('-pk')
|
||||||
|
try:
|
||||||
|
return qs[0]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
def in_bulk(self, id_list):
|
def in_bulk(self, id_list):
|
||||||
"""
|
"""
|
||||||
Returns a dictionary mapping each of the given IDs to the object with
|
Returns a dictionary mapping each of the given IDs to the object with
|
||||||
|
|
|
@ -1585,6 +1585,36 @@ earliest
|
||||||
Works otherwise like :meth:`~django.db.models.query.QuerySet.latest` except
|
Works otherwise like :meth:`~django.db.models.query.QuerySet.latest` except
|
||||||
the direction is changed.
|
the direction is changed.
|
||||||
|
|
||||||
|
first
|
||||||
|
~~~~~
|
||||||
|
.. method:: first()
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
Returns the first object matched by the queryset, or ``None`` if there
|
||||||
|
is no matching object. If the ``QuerySet`` has no ordering defined, then the
|
||||||
|
queryset is automatically ordered by the primary key.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
p = Article.objects.order_by('title', 'pub_date').first()
|
||||||
|
|
||||||
|
Note that ``first()`` is a convenience method, the following code sample is
|
||||||
|
equivalent to the above example::
|
||||||
|
|
||||||
|
try:
|
||||||
|
p = Article.objects.order_by('title', 'pub_date')[0]
|
||||||
|
except IndexError:
|
||||||
|
p = None
|
||||||
|
|
||||||
|
last
|
||||||
|
~~~~
|
||||||
|
.. method:: last()
|
||||||
|
|
||||||
|
.. versionadded:: 1.6
|
||||||
|
|
||||||
|
Works like :meth:`first()` except the ordering is reversed.
|
||||||
|
|
||||||
aggregate
|
aggregate
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,11 @@ Minor features
|
||||||
allow users to specify the primary keys of objects they want to dump.
|
allow users to specify the primary keys of objects they want to dump.
|
||||||
This option can only be used with one model.
|
This option can only be used with one model.
|
||||||
|
|
||||||
|
* Added ``QuerySet`` methods :meth:`~django.db.models.query.QuerySet.first`
|
||||||
|
and :meth:`~django.db.models.query.QuerySet.last` which are convenience
|
||||||
|
methods returning the first or last object matching the filters. Returns
|
||||||
|
``None`` if there are no objects matching.
|
||||||
|
|
||||||
Backwards incompatible changes in 1.6
|
Backwards incompatible changes in 1.6
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
|
@ -121,3 +121,34 @@ class EarliestOrLatestTests(TestCase):
|
||||||
p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
|
p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
|
||||||
self.assertRaises(AssertionError, Person.objects.latest)
|
self.assertRaises(AssertionError, Person.objects.latest)
|
||||||
self.assertEqual(Person.objects.latest("birthday"), p2)
|
self.assertEqual(Person.objects.latest("birthday"), p2)
|
||||||
|
|
||||||
|
def test_first(self):
|
||||||
|
p1 = Person.objects.create(name="Bob", birthday=datetime(1950, 1, 1))
|
||||||
|
p2 = Person.objects.create(name="Alice", birthday=datetime(1961, 2, 3))
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.first(), p1)
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.order_by('name').first(), p2)
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.filter(birthday__lte=datetime(1955, 1, 1)).first(),
|
||||||
|
p1)
|
||||||
|
self.assertIs(
|
||||||
|
Person.objects.filter(birthday__lte=datetime(1940, 1, 1)).first(),
|
||||||
|
None)
|
||||||
|
|
||||||
|
def test_last(self):
|
||||||
|
p1 = Person.objects.create(
|
||||||
|
name="Alice", birthday=datetime(1950, 1, 1))
|
||||||
|
p2 = Person.objects.create(
|
||||||
|
name="Bob", birthday=datetime(1960, 2, 3))
|
||||||
|
# Note: by default PK ordering.
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.last(), p2)
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.order_by('-name').last(), p1)
|
||||||
|
self.assertEqual(
|
||||||
|
Person.objects.filter(birthday__lte=datetime(1955, 1, 1)).last(),
|
||||||
|
p1)
|
||||||
|
self.assertIs(
|
||||||
|
Person.objects.filter(birthday__lte=datetime(1940, 1, 1)).last(),
|
||||||
|
None)
|
||||||
|
|
Loading…
Reference in New Issue