tests.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. from __future__ import unicode_literals
  2. from datetime import datetime
  3. from django.test import TestCase
  4. from .models import Article, IndexErrorArticle, Person
  5. class EarliestOrLatestTests(TestCase):
  6. """Tests for the earliest() and latest() objects methods"""
  7. def tearDown(self):
  8. """Makes sure Article has a get_latest_by"""
  9. if not Article._meta.get_latest_by:
  10. Article._meta.get_latest_by = 'pub_date'
  11. def test_earliest(self):
  12. # Because no Articles exist yet, earliest() raises ArticleDoesNotExist.
  13. with self.assertRaises(Article.DoesNotExist):
  14. Article.objects.earliest()
  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. Article.objects.create(
  24. headline="Article 3", pub_date=datetime(2005, 7, 28),
  25. expire_date=datetime(2005, 8, 27)
  26. )
  27. Article.objects.create(
  28. headline="Article 4", pub_date=datetime(2005, 7, 28),
  29. expire_date=datetime(2005, 7, 30)
  30. )
  31. # Get the earliest Article.
  32. self.assertEqual(Article.objects.earliest(), a1)
  33. # Get the earliest Article that matches certain filters.
  34. self.assertEqual(
  35. Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).earliest(),
  36. a2
  37. )
  38. # Pass a custom field name to earliest() to change the field that's used
  39. # to determine the earliest object.
  40. self.assertEqual(Article.objects.earliest('expire_date'), a2)
  41. self.assertEqual(Article.objects.filter(
  42. pub_date__gt=datetime(2005, 7, 26)).earliest('expire_date'), a2)
  43. # earliest() overrides any other ordering specified on the query.
  44. # Refs #11283.
  45. self.assertEqual(Article.objects.order_by('id').earliest(), a1)
  46. # Error is raised if the user forgot to add a get_latest_by
  47. # in the Model.Meta
  48. Article.objects.model._meta.get_latest_by = None
  49. with self.assertRaisesMessage(
  50. AssertionError,
  51. "earliest() and latest() require either a field_name parameter or "
  52. "'get_latest_by' in the model"
  53. ):
  54. Article.objects.earliest()
  55. def test_latest(self):
  56. # Because no Articles exist yet, latest() raises ArticleDoesNotExist.
  57. with self.assertRaises(Article.DoesNotExist):
  58. Article.objects.latest()
  59. a1 = Article.objects.create(
  60. headline="Article 1", pub_date=datetime(2005, 7, 26),
  61. expire_date=datetime(2005, 9, 1)
  62. )
  63. Article.objects.create(
  64. headline="Article 2", pub_date=datetime(2005, 7, 27),
  65. expire_date=datetime(2005, 7, 28)
  66. )
  67. a3 = Article.objects.create(
  68. headline="Article 3", pub_date=datetime(2005, 7, 27),
  69. expire_date=datetime(2005, 8, 27)
  70. )
  71. a4 = Article.objects.create(
  72. headline="Article 4", pub_date=datetime(2005, 7, 28),
  73. expire_date=datetime(2005, 7, 30)
  74. )
  75. # Get the latest Article.
  76. self.assertEqual(Article.objects.latest(), a4)
  77. # Get the latest Article that matches certain filters.
  78. self.assertEqual(
  79. Article.objects.filter(pub_date__lt=datetime(2005, 7, 27)).latest(),
  80. a1
  81. )
  82. # Pass a custom field name to latest() to change the field that's used
  83. # to determine the latest object.
  84. self.assertEqual(Article.objects.latest('expire_date'), a1)
  85. self.assertEqual(
  86. Article.objects.filter(pub_date__gt=datetime(2005, 7, 26)).latest('expire_date'),
  87. a3,
  88. )
  89. # latest() overrides any other ordering specified on the query (#11283).
  90. self.assertEqual(Article.objects.order_by('id').latest(), a4)
  91. # Error is raised if get_latest_by isn't in Model.Meta.
  92. Article.objects.model._meta.get_latest_by = None
  93. with self.assertRaisesMessage(
  94. AssertionError,
  95. "earliest() and latest() require either a field_name parameter or "
  96. "'get_latest_by' in the model"
  97. ):
  98. Article.objects.latest()
  99. def test_latest_manual(self):
  100. # You can still use latest() with a model that doesn't have
  101. # "get_latest_by" set -- just pass in the field name manually.
  102. Person.objects.create(name="Ralph", birthday=datetime(1950, 1, 1))
  103. p2 = Person.objects.create(name="Stephanie", birthday=datetime(1960, 2, 3))
  104. with self.assertRaises(AssertionError):
  105. Person.objects.latest()
  106. self.assertEqual(Person.objects.latest("birthday"), p2)
  107. class TestFirstLast(TestCase):
  108. def test_first(self):
  109. p1 = Person.objects.create(name="Bob", birthday=datetime(1950, 1, 1))
  110. p2 = Person.objects.create(name="Alice", birthday=datetime(1961, 2, 3))
  111. self.assertEqual(Person.objects.first(), p1)
  112. self.assertEqual(Person.objects.order_by('name').first(), p2)
  113. self.assertEqual(Person.objects.filter(birthday__lte=datetime(1955, 1, 1)).first(), p1)
  114. self.assertIsNone(Person.objects.filter(birthday__lte=datetime(1940, 1, 1)).first())
  115. def test_last(self):
  116. p1 = Person.objects.create(name="Alice", birthday=datetime(1950, 1, 1))
  117. p2 = Person.objects.create(name="Bob", birthday=datetime(1960, 2, 3))
  118. # Note: by default PK ordering.
  119. self.assertEqual(Person.objects.last(), p2)
  120. self.assertEqual(Person.objects.order_by('-name').last(), p1)
  121. self.assertEqual(Person.objects.filter(birthday__lte=datetime(1955, 1, 1)).last(), p1)
  122. self.assertIsNone(Person.objects.filter(birthday__lte=datetime(1940, 1, 1)).last())
  123. def test_index_error_not_suppressed(self):
  124. """
  125. #23555 -- Unexpected IndexError exceptions in QuerySet iteration
  126. shouldn't be suppressed.
  127. """
  128. def check():
  129. # We know that we've broken the __iter__ method, so the queryset
  130. # should always raise an exception.
  131. with self.assertRaises(IndexError):
  132. IndexErrorArticle.objects.all()[0]
  133. with self.assertRaises(IndexError):
  134. IndexErrorArticle.objects.all().first()
  135. with self.assertRaises(IndexError):
  136. IndexErrorArticle.objects.all().last()
  137. check()
  138. # And it does not matter if there are any records in the DB.
  139. IndexErrorArticle.objects.create(
  140. headline="Article 1", pub_date=datetime(2005, 7, 26),
  141. expire_date=datetime(2005, 9, 1)
  142. )
  143. check()