Ticket #17813: t17813.3.diff
File t17813.3.diff, 14.7 KB (added by , 13 years ago) |
---|
-
django/db/models/manager.py
diff --git a/django/db/models/manager.py b/django/db/models/manager.py index e1bbf6e..cc00fed 100644
a b class Manager(object): 160 160 def iterator(self, *args, **kwargs): 161 161 return self.get_query_set().iterator(*args, **kwargs) 162 162 163 def earliest(self, *args, **kwargs): 164 return self.get_query_set().earliest(*args, **kwargs) 165 163 166 def latest(self, *args, **kwargs): 164 167 return self.get_query_set().latest(*args, **kwargs) 165 168 -
django/db/models/query.py
diff --git a/django/db/models/query.py b/django/db/models/query.py index 44acadf..4fa38df 100644
a b class QuerySet(object): 458 458 # Re-raise the IntegrityError with its original traceback. 459 459 raise exc_info[1], None, exc_info[2] 460 460 461 def latest(self, field_name=None):461 def _earliest_or_latest(self, field_name=None, direction="-"): 462 462 """ 463 Returns the latest object, according to the model's 'get_latest_by'464 option or optional given field_name.463 Returns the latest object, according to the model's 464 'get_latest_by' option or optional given field_name. 465 465 """ 466 latest_by = field_name or self.model._meta.get_latest_by 467 assert bool(latest_by), "latest() requires either a field_name parameter or 'get_latest_by' in the model" 466 order_by = field_name or getattr(self.model._meta, 'get_latest_by') 467 assert bool(order_by), "_earliest_or_latest() requires either a "\ 468 "field_name parameter or 'get_latest_by' in the model" 468 469 assert self.query.can_filter(), \ 469 470 "Cannot change a query once a slice has been taken." 470 471 obj = self._clone() 471 472 obj.query.set_limits(high=1) 472 473 obj.query.clear_ordering() 473 obj.query.add_ordering(' -%s' % latest_by)474 obj.query.add_ordering('%s%s' % (direction, order_by)) 474 475 return obj.get() 475 476 477 def earliest(self, field_name=None): 478 return self._earliest_or_latest(field_name=field_name, direction="") 479 480 def latest(self, field_name=None): 481 return self._earliest_or_latest(field_name=field_name, direction="-") 482 476 483 def in_bulk(self, id_list): 477 484 """ 478 485 Returns a dictionary mapping each of the given IDs to the object with -
docs/ref/models/options.txt
diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt index 6ca3d3b..3e77b8b 100644
a b Django quotes column and table names behind the scenes. 78 78 setting, if set. If the backend doesn't support tablespaces, this option is 79 79 ignored. 80 80 81 81 82 ``get_latest_by`` 82 83 ----------------- 83 84 -
docs/ref/models/querysets.txt
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index e25bea0..34e3fac 100644
a b This example returns the latest ``Entry`` in the table, according to the 1466 1466 1467 1467 If your model's :ref:`Meta <meta-options>` specifies 1468 1468 :attr:`~django.db.models.Options.get_latest_by`, you can leave off the 1469 ``field_name`` argument to `` latest()``. Django will use the field specified1470 in :attr:`~django.db.models.Options.get_latest_by` by default.1469 ``field_name`` argument to ``earliest()`` or ``latest()``. Django will use the 1470 field specified in :attr:`~django.db.models.Options.get_latest_by` by default. 1471 1471 1472 Like :meth:`get()`, `` latest()`` raises1473 :exc:`~django.core.exceptions.DoesNotExist` if there is no object with the given1474 parameters.1472 Like :meth:`get()`, ``earliest()`` and ``latest()`` raise 1473 :exc:`~django.core.exceptions.DoesNotExist` if there is no object with the 1474 given parameters. 1475 1475 1476 Note ``latest()`` exists purely for convenience and readability. 1476 Note that ``earliest()`` and ``latest()`` exist purely for convenience and 1477 readability. 1477 1478 1478 1479 aggregate 1479 1480 ~~~~~~~~~ -
docs/topics/db/models.txt
diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 9a4010d..14f216d 100644
a b right). 991 991 992 992 So a child model does not have access to its parent's :ref:`Meta 993 993 <meta-options>` class. However, there are a few limited cases where the child 994 inherits behavior from the parent: if the child does not specify an 995 :attr:`~django.db.models.Options.ordering` attribute or a996 :attr:`~django.db.models.Options.get_latest_by` attribute, it will inherit997 these from its parent.994 inherits behavior from the parent: if the child does not specify an attribute 995 :attr:`~django.db.models.Options.ordering` or 996 :attr:`~django.db.models.Options.get_latest_by`, 997 , it will inherit these from its parent. 998 998 999 999 If the parent has an ordering and you don't want the child to have any natural 1000 1000 ordering, you can explicitly disable it:: -
new file tests/modeltests/get_earliest_or_latest/models.py
diff --git a/tests/modeltests/get_earliest_or_latest/__init__.py b/tests/modeltests/get_earliest_or_latest/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/modeltests/get_earliest_or_latest/models.py b/tests/modeltests/get_earliest_or_latest/models.py new file mode 100644 index 0000000..2453eaa
- + 1 """ 2 8. get_latest_by 3 4 Models can have a ``get_latest_by`` attribute, which should be set to the name 5 of a ``DateField`` or ``DateTimeField``. If ``get_latest_by`` exists, the 6 model's manager will get a ``latest()`` method, which will return the latest 7 object in the database according to that field. "Latest" means "having the date 8 farthest into the future." 9 """ 10 11 from django.db import models 12 13 14 class Article(models.Model): 15 headline = models.CharField(max_length=100) 16 pub_date = models.DateField() 17 expire_date = models.DateField() 18 class Meta: 19 get_latest_by = 'pub_date' 20 21 def __unicode__(self): 22 return self.headline 23 24 25 class Person(models.Model): 26 name = models.CharField(max_length=30) 27 birthday = models.DateField() 28 29 # Note that this model doesn't have "get_latest_by" set. 30 31 def __unicode__(self): 32 return self.name -
new file tests/modeltests/get_earliest_or_latest/tests.py
diff --git a/tests/modeltests/get_earliest_or_latest/tests.py b/tests/modeltests/get_earliest_or_latest/tests.py new file mode 100644 index 0000000..a78af2a
- + 1 from __future__ import absolute_import 2 3 from datetime import datetime 4 5 from django.test import TestCase 6 7 from .models import Article, Person 8 9 10 class EarliestOrLatestTests(TestCase): 11 """Tests for the earliest() and latest() objects methods""" 12 13 def test_earliest(self): 14 # Because no Articles exist yet, earliest() raises ArticleDoesNotExist. 15 self.assertRaises(Article.DoesNotExist, Article.objects.earliest) 16 17 a1 = Article.objects.create( 18 headline="Article 1", pub_date=datetime(2005, 7, 26), 19 expire_date=datetime(2005, 9, 1) 20 ) 21 a2 = Article.objects.create( 22 headline="Article 2", pub_date=datetime(2005, 7, 27), 23 expire_date=datetime(2005, 7, 28) 24 ) 25 a3 = Article.objects.create( 26 headline="Article 3", pub_date=datetime(2005, 7, 28), 27 expire_date=datetime(2005, 8, 27) 28 ) 29 a4 = Article.objects.create( 30 headline="Article 4", pub_date=datetime(2005, 7, 28), 31 expire_date=datetime(2005, 7, 30) 32 ) 33 34 # Get the earliest Article. 35 self.assertEqual(Article.objects.earliest(), a1) 36 # Get the earliest Article that matches certain filters. 37 self.assertEqual( 38 Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).earliest(), 39 a2 40 ) 41 42 # Pass a custom field name to earliest() to change the field that's used 43 # to determine the earliest object. 44 self.assertEqual(Article.objects.earliest('expire_date'), a2) 45 self.assertEqual(Article.objects.filter( 46 pub_date__gt=datetime(2005, 7, 26)).earliest('expire_date'), a2) 47 48 # Ensure that earliest() overrides any other ordering specified on the 49 # query. Refs #11283. 50 self.assertEqual(Article.objects.order_by('id').earliest(), a1) 51 52 # Ensure that error is raised if the user forgot to add a get_earliest_by 53 # in the Model.Meta 54 Article.objects.model._meta.get_earliest_by = None 55 self.assertRaisesMessage( 56 AssertionError, 57 "_earliest_or_latest() requires either a field_name parameter or "\ 58 "'get_earliest_by' in the model", 59 lambda: Article.objects.earliest(), 60 ) 61 62 63 def test_latest(self): 64 # Because no Articles exist yet, latest() raises ArticleDoesNotExist. 65 self.assertRaises(Article.DoesNotExist, Article.objects.latest) 66 67 a1 = Article.objects.create( 68 headline="Article 1", pub_date=datetime(2005, 7, 26), 69 expire_date=datetime(2005, 9, 1) 70 ) 71 a2 = Article.objects.create( 72 headline="Article 2", pub_date=datetime(2005, 7, 27), 73 expire_date=datetime(2005, 7, 28) 74 ) 75 a3 = Article.objects.create( 76 headline="Article 3", pub_date=datetime(2005, 7, 27), 77 expire_date=datetime(2005, 8, 27) 78 ) 79 a4 = Article.objects.create( 80 headline="Article 4", pub_date=datetime(2005, 7, 28), 81 expire_date=datetime(2005, 7, 30) 82 ) 83 84 # Get the latest Article. 85 self.assertEqual(Article.objects.latest(), a4) 86 # Get the latest Article that matches certain filters. 87 self.assertEqual( 88 Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest(), 89 a1 90 ) 91 92 # Pass a custom field name to latest() to change the field that's used 93 # to determine the latest object. 94 self.assertEqual(Article.objects.latest('expire_date'), a1) 95 self.assertEqual( 96 Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date'), 97 a3, 98 ) 99 100 # Ensure that latest() overrides any other ordering specified on the query. Refs #11283. 101 self.assertEqual(Article.objects.order_by('id').latest(), a4) 102 103 # Ensure that error is raised if the user forgot to add a get_latest_by 104 # in the Model.Meta 105 Article.objects.model._meta.get_latest_by = None 106 self.assertRaisesMessage( 107 AssertionError, 108 "_earliest_or_latest() requires either a field_name parameter or "\ 109 "'get_latest_by' in the model", 110 lambda: Article.objects.latest(), 111 ) 112 113 114 def test_latest_manual(self): 115 # You can still use latest() with a model that doesn't have 116 # "get_latest_by" set -- just pass in the field name manually. 117 p1 = Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1)) 118 p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3)) 119 self.assertRaises(AssertionError, Person.objects.latest) 120 121 self.assertEqual(Person.objects.latest("birthday"), p2) -
deleted file tests/modeltests/get_latest/models.py
diff --git a/tests/modeltests/get_latest/__init__.py b/tests/modeltests/get_latest/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/modeltests/get_latest/models.py b/tests/modeltests/get_latest/models.py deleted file mode 100644 index d8a690f..0000000
+ - 1 """2 8. get_latest_by3 4 Models can have a ``get_latest_by`` attribute, which should be set to the name5 of a ``DateField`` or ``DateTimeField``. If ``get_latest_by`` exists, the6 model's manager will get a ``latest()`` method, which will return the latest7 object in the database according to that field. "Latest" means "having the date8 farthest into the future."9 """10 11 from django.db import models12 13 14 class Article(models.Model):15 headline = models.CharField(max_length=100)16 pub_date = models.DateField()17 expire_date = models.DateField()18 class Meta:19 get_latest_by = 'pub_date'20 21 def __unicode__(self):22 return self.headline23 24 class Person(models.Model):25 name = models.CharField(max_length=30)26 birthday = models.DateField()27 28 # Note that this model doesn't have "get_latest_by" set.29 30 def __unicode__(self):31 return self.name -
deleted file tests/modeltests/get_latest/tests.py
diff --git a/tests/modeltests/get_latest/tests.py b/tests/modeltests/get_latest/tests.py deleted file mode 100644 index 948af60..0000000
+ - 1 from __future__ import absolute_import2 3 from datetime import datetime4 5 from django.test import TestCase6 7 from .models import Article, Person8 9 10 class LatestTests(TestCase):11 def test_latest(self):12 # Because no Articles exist yet, latest() raises ArticleDoesNotExist.13 self.assertRaises(Article.DoesNotExist, Article.objects.latest)14 15 a1 = Article.objects.create(16 headline="Article 1", pub_date=datetime(2005, 7, 26),17 expire_date=datetime(2005, 9, 1)18 )19 a2 = Article.objects.create(20 headline="Article 2", pub_date=datetime(2005, 7, 27),21 expire_date=datetime(2005, 7, 28)22 )23 a3 = Article.objects.create(24 headline="Article 3", pub_date=datetime(2005, 7, 27),25 expire_date=datetime(2005, 8, 27)26 )27 a4 = Article.objects.create(28 headline="Article 4", pub_date=datetime(2005, 7, 28),29 expire_date=datetime(2005, 7, 30)30 )31 32 # Get the latest Article.33 self.assertEqual(Article.objects.latest(), a4)34 # Get the latest Article that matches certain filters.35 self.assertEqual(36 Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest(),37 a138 )39 40 # Pass a custom field name to latest() to change the field that's used41 # to determine the latest object.42 self.assertEqual(Article.objects.latest('expire_date'), a1)43 self.assertEqual(44 Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date'),45 a3,46 )47 48 # Ensure that latest() overrides any other ordering specified on the query. Refs #11283.49 self.assertEqual(Article.objects.order_by('id').latest(), a4)50 51 def test_latest_manual(self):52 # You can still use latest() with a model that doesn't have53 # "get_latest_by" set -- just pass in the field name manually.54 p1 = Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1))55 p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))56 self.assertRaises(AssertionError, Person.objects.latest)57 58 self.assertEqual(Person.objects.latest("birthday"), p2)