tests.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. from datetime import datetime
  2. from math import pi
  3. from django.db import connection
  4. from django.db.models import Case, F, FloatField, Value, When
  5. from django.db.models.expressions import (
  6. Expression,
  7. ExpressionList,
  8. ExpressionWrapper,
  9. Func,
  10. OrderByList,
  11. RawSQL,
  12. )
  13. from django.db.models.functions import Collate
  14. from django.db.models.lookups import GreaterThan
  15. from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature
  16. from .models import (
  17. Article,
  18. DBArticle,
  19. DBDefaults,
  20. DBDefaultsFK,
  21. DBDefaultsFunction,
  22. DBDefaultsPK,
  23. )
  24. class DefaultTests(TestCase):
  25. def test_field_defaults(self):
  26. a = Article()
  27. now = datetime.now()
  28. a.save()
  29. self.assertIsInstance(a.id, int)
  30. self.assertEqual(a.headline, "Default headline")
  31. self.assertLess((now - a.pub_date).seconds, 5)
  32. @skipUnlessDBFeature(
  33. "can_return_columns_from_insert", "supports_expression_defaults"
  34. )
  35. def test_field_db_defaults_returning(self):
  36. a = DBArticle()
  37. a.save()
  38. self.assertIsInstance(a.id, int)
  39. self.assertEqual(a.headline, "Default headline")
  40. self.assertIsInstance(a.pub_date, datetime)
  41. @skipIfDBFeature("can_return_columns_from_insert")
  42. @skipUnlessDBFeature("supports_expression_defaults")
  43. def test_field_db_defaults_refresh(self):
  44. a = DBArticle()
  45. a.save()
  46. a.refresh_from_db()
  47. self.assertIsInstance(a.id, int)
  48. self.assertEqual(a.headline, "Default headline")
  49. self.assertIsInstance(a.pub_date, datetime)
  50. def test_null_db_default(self):
  51. obj1 = DBDefaults.objects.create()
  52. if not connection.features.can_return_columns_from_insert:
  53. obj1.refresh_from_db()
  54. self.assertEqual(obj1.null, 1.1)
  55. obj2 = DBDefaults.objects.create(null=None)
  56. self.assertIsNone(obj2.null)
  57. @skipUnlessDBFeature("supports_expression_defaults")
  58. def test_db_default_function(self):
  59. m = DBDefaultsFunction.objects.create()
  60. if not connection.features.can_return_columns_from_insert:
  61. m.refresh_from_db()
  62. self.assertAlmostEqual(m.number, pi)
  63. self.assertEqual(m.year, datetime.now().year)
  64. self.assertAlmostEqual(m.added, pi + 4.5)
  65. self.assertEqual(m.multiple_subfunctions, 4.5)
  66. @skipUnlessDBFeature("insert_test_table_with_defaults")
  67. def test_both_default(self):
  68. create_sql = connection.features.insert_test_table_with_defaults
  69. with connection.cursor() as cursor:
  70. cursor.execute(create_sql.format(DBDefaults._meta.db_table))
  71. obj1 = DBDefaults.objects.get()
  72. self.assertEqual(obj1.both, 2)
  73. obj2 = DBDefaults.objects.create()
  74. self.assertEqual(obj2.both, 1)
  75. def test_pk_db_default(self):
  76. obj1 = DBDefaultsPK.objects.create()
  77. if not connection.features.can_return_columns_from_insert:
  78. # refresh_from_db() cannot be used because that needs the pk to
  79. # already be known to Django.
  80. obj1 = DBDefaultsPK.objects.get(pk="en")
  81. self.assertEqual(obj1.pk, "en")
  82. self.assertEqual(obj1.language_code, "en")
  83. obj2 = DBDefaultsPK.objects.create(language_code="de")
  84. self.assertEqual(obj2.pk, "de")
  85. self.assertEqual(obj2.language_code, "de")
  86. def test_foreign_key_db_default(self):
  87. parent1 = DBDefaultsPK.objects.create(language_code="fr")
  88. child1 = DBDefaultsFK.objects.create()
  89. if not connection.features.can_return_columns_from_insert:
  90. child1.refresh_from_db()
  91. self.assertEqual(child1.language_code, parent1)
  92. parent2 = DBDefaultsPK.objects.create()
  93. if not connection.features.can_return_columns_from_insert:
  94. # refresh_from_db() cannot be used because that needs the pk to
  95. # already be known to Django.
  96. parent2 = DBDefaultsPK.objects.get(pk="en")
  97. child2 = DBDefaultsFK.objects.create(language_code=parent2)
  98. self.assertEqual(child2.language_code, parent2)
  99. @skipUnlessDBFeature(
  100. "can_return_columns_from_insert", "supports_expression_defaults"
  101. )
  102. def test_case_when_db_default_returning(self):
  103. m = DBDefaultsFunction.objects.create()
  104. self.assertEqual(m.case_when, 3)
  105. @skipIfDBFeature("can_return_columns_from_insert")
  106. @skipUnlessDBFeature("supports_expression_defaults")
  107. def test_case_when_db_default_no_returning(self):
  108. m = DBDefaultsFunction.objects.create()
  109. m.refresh_from_db()
  110. self.assertEqual(m.case_when, 3)
  111. @skipUnlessDBFeature("supports_expression_defaults")
  112. def test_bulk_create_all_db_defaults(self):
  113. articles = [DBArticle(), DBArticle()]
  114. DBArticle.objects.bulk_create(articles)
  115. headlines = DBArticle.objects.values_list("headline", flat=True)
  116. self.assertSequenceEqual(headlines, ["Default headline", "Default headline"])
  117. @skipUnlessDBFeature("supports_expression_defaults")
  118. def test_bulk_create_all_db_defaults_one_field(self):
  119. pub_date = datetime.now()
  120. articles = [DBArticle(pub_date=pub_date), DBArticle(pub_date=pub_date)]
  121. DBArticle.objects.bulk_create(articles)
  122. headlines = DBArticle.objects.values_list("headline", "pub_date")
  123. self.assertSequenceEqual(
  124. headlines,
  125. [
  126. ("Default headline", pub_date),
  127. ("Default headline", pub_date),
  128. ],
  129. )
  130. @skipUnlessDBFeature("supports_expression_defaults")
  131. def test_bulk_create_mixed_db_defaults(self):
  132. articles = [DBArticle(), DBArticle(headline="Something else")]
  133. DBArticle.objects.bulk_create(articles)
  134. headlines = DBArticle.objects.values_list("headline", flat=True)
  135. self.assertCountEqual(headlines, ["Default headline", "Something else"])
  136. @skipUnlessDBFeature("supports_expression_defaults")
  137. def test_bulk_create_mixed_db_defaults_function(self):
  138. instances = [DBDefaultsFunction(), DBDefaultsFunction(year=2000)]
  139. DBDefaultsFunction.objects.bulk_create(instances)
  140. years = DBDefaultsFunction.objects.values_list("year", flat=True)
  141. self.assertCountEqual(years, [2000, datetime.now().year])
  142. class AllowedDefaultTests(SimpleTestCase):
  143. def test_allowed(self):
  144. class Max(Func):
  145. function = "MAX"
  146. tests = [
  147. Value(10),
  148. Max(1, 2),
  149. RawSQL("Now()", ()),
  150. Value(10) + Value(7), # Combined expression.
  151. ExpressionList(Value(1), Value(2)),
  152. ExpressionWrapper(Value(1), output_field=FloatField()),
  153. Case(When(GreaterThan(2, 1), then=3), default=4),
  154. ]
  155. for expression in tests:
  156. with self.subTest(expression=expression):
  157. self.assertIs(expression.allowed_default, True)
  158. def test_disallowed(self):
  159. class Max(Func):
  160. function = "MAX"
  161. tests = [
  162. Expression(),
  163. F("field"),
  164. Max(F("count"), 1),
  165. Value(10) + F("count"), # Combined expression.
  166. ExpressionList(F("count"), Value(2)),
  167. ExpressionWrapper(F("count"), output_field=FloatField()),
  168. Collate(Value("John"), "nocase"),
  169. OrderByList("field"),
  170. ]
  171. for expression in tests:
  172. with self.subTest(expression=expression):
  173. self.assertIs(expression.allowed_default, False)