diff --git a/django/db/models/query.py b/django/db/models/query.py index f92998e7ad..5d76a34580 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -25,7 +25,6 @@ from django.db.models.query_utils import FilteredRelation, InvalidQuery, Q from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE from django.db.utils import NotSupportedError from django.utils import timezone -from django.utils.deprecation import RemovedInDjango30Warning from django.utils.functional import cached_property, partition from django.utils.version import get_version @@ -607,22 +606,12 @@ class QuerySet: )) return params - def _earliest(self, *fields, field_name=None): + def _earliest(self, *fields): """ Return the earliest object according to fields (if given) or by the model's Meta.get_latest_by. """ - if fields and field_name is not None: - raise ValueError('Cannot use both positional arguments and the field_name keyword argument.') - - if field_name is not None: - warnings.warn( - 'The field_name keyword argument to earliest() and latest() ' - 'is deprecated in favor of passing positional arguments.', - RemovedInDjango30Warning, - ) - order_by = (field_name,) - elif fields: + if fields: order_by = fields else: order_by = getattr(self.model._meta, 'get_latest_by') @@ -642,11 +631,11 @@ class QuerySet: obj.query.add_ordering(*order_by) return obj.get() - def earliest(self, *fields, field_name=None): - return self._earliest(*fields, field_name=field_name) + def earliest(self, *fields): + return self._earliest(*fields) - def latest(self, *fields, field_name=None): - return self.reverse()._earliest(*fields, field_name=field_name) + def latest(self, *fields): + return self.reverse()._earliest(*fields) def first(self): """Return the first object of a query or None if no match is found.""" diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index b49708f675..7699603dea 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -247,6 +247,9 @@ to remove usage of these features. * Support for the ``context`` argument of ``Field.from_db_value()`` and ``Expression.convert_value()`` is removed. +* The ``field_name`` keyword argument of ``QuerySet.earliest()` and + ``latest()`` is removed. + See :ref:`deprecated-features-2.1` for details on these changes, including how to remove usage of these features. diff --git a/tests/get_earliest_or_latest/tests.py b/tests/get_earliest_or_latest/tests.py index a49dc43402..96ebe19f32 100644 --- a/tests/get_earliest_or_latest/tests.py +++ b/tests/get_earliest_or_latest/tests.py @@ -1,7 +1,6 @@ from datetime import datetime from django.test import TestCase -from django.utils.deprecation import RemovedInDjango30Warning from .models import Article, IndexErrorArticle, Person @@ -82,11 +81,6 @@ class EarliestOrLatestTests(TestCase): Article.objects.model._meta.get_latest_by = ('pub_date', 'expire_date') self.assertEqual(Article.objects.filter(pub_date=datetime(2005, 7, 28)).earliest(), a4) - def test_earliest_fields_and_field_name(self): - msg = 'Cannot use both positional arguments and the field_name keyword argument.' - with self.assertRaisesMessage(ValueError, msg): - Article.objects.earliest('pub_date', field_name='expire_date') - def test_latest(self): # Because no Articles exist yet, latest() raises ArticleDoesNotExist. with self.assertRaises(Article.DoesNotExist): @@ -149,11 +143,6 @@ class EarliestOrLatestTests(TestCase): Article.objects.model._meta.get_latest_by = ('pub_date', 'expire_date') self.assertEqual(Article.objects.filter(pub_date=datetime(2005, 7, 27)).latest(), a3) - def test_latest_fields_and_field_name(self): - msg = 'Cannot use both positional arguments and the field_name keyword argument.' - with self.assertRaisesMessage(ValueError, msg): - Article.objects.latest('pub_date', field_name='expire_date') - def test_latest_manual(self): # You can still use latest() with a model that doesn't have # "get_latest_by" set -- just pass in the field name manually. @@ -167,15 +156,6 @@ class EarliestOrLatestTests(TestCase): Person.objects.latest() self.assertEqual(Person.objects.latest("birthday"), p2) - def test_field_name_kwarg_deprecation(self): - Person.objects.create(name='Deprecator', birthday=datetime(1950, 1, 1)) - msg = ( - 'The field_name keyword argument to earliest() and latest() ' - 'is deprecated in favor of passing positional arguments.' - ) - with self.assertWarnsMessage(RemovedInDjango30Warning, msg): - Person.objects.latest(field_name='birthday') - class TestFirstLast(TestCase):