diff --git a/django/db/models/query.py b/django/db/models/query.py
a
|
b
|
|
392 | 392 | except self.model.DoesNotExist: |
393 | 393 | raise e |
394 | 394 | |
395 | | def latest(self, field_name=None): |
| 395 | def _first_or_latest(self, field_name=None, direction="-"): |
396 | 396 | """ |
397 | 397 | Returns the latest object, according to the model's 'get_latest_by' |
398 | 398 | option or optional given field_name. |
399 | 399 | """ |
400 | | latest_by = field_name or self.model._meta.get_latest_by |
401 | | assert bool(latest_by), "latest() requires either a field_name parameter or 'get_latest_by' in the model" |
| 400 | order_by = field_name or self.model._meta.get_latest_by |
| 401 | assert bool(order_by), "latest() requires either a field_name parameter or 'get_latest_by' in the model" |
402 | 402 | assert self.query.can_filter(), \ |
403 | 403 | "Cannot change a query once a slice has been taken." |
404 | 404 | obj = self._clone() |
405 | 405 | obj.query.set_limits(high=1) |
406 | | obj.query.add_ordering('-%s' % latest_by) |
| 406 | obj.query.add_ordering('%s%s' % (direction, order_by)) |
407 | 407 | return obj.get() |
408 | 408 | |
| 409 | def first(self, field_name=None): |
| 410 | return self._first_or_latest(field_name=field_name, direction="+") |
| 411 | |
| 412 | def latest(self, field_name=None): |
| 413 | return self._first_or_latest(field_name=field_name, direction="-") |
| 414 | |
409 | 415 | def in_bulk(self, id_list): |
410 | 416 | """ |
411 | 417 | Returns a dictionary mapping each of the given IDs to the object with |