tests.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import pickle
  2. from django import forms
  3. from django.db import models
  4. from django.test import SimpleTestCase, TestCase
  5. from django.utils.functional import lazy
  6. from .models import (
  7. Bar, Foo, RenamedField, VerboseNameField, Whiz, WhizIter, WhizIterEmpty,
  8. )
  9. class Nested:
  10. class Field(models.Field):
  11. pass
  12. class BasicFieldTests(SimpleTestCase):
  13. def test_show_hidden_initial(self):
  14. """
  15. Fields with choices respect show_hidden_initial as a kwarg to
  16. formfield().
  17. """
  18. choices = [(0, 0), (1, 1)]
  19. model_field = models.Field(choices=choices)
  20. form_field = model_field.formfield(show_hidden_initial=True)
  21. self.assertTrue(form_field.show_hidden_initial)
  22. form_field = model_field.formfield(show_hidden_initial=False)
  23. self.assertFalse(form_field.show_hidden_initial)
  24. def test_field_repr(self):
  25. """
  26. __repr__() of a field displays its name.
  27. """
  28. f = Foo._meta.get_field('a')
  29. self.assertEqual(repr(f), '<django.db.models.fields.CharField: a>')
  30. f = models.fields.CharField()
  31. self.assertEqual(repr(f), '<django.db.models.fields.CharField>')
  32. def test_field_repr_nested(self):
  33. """__repr__() uses __qualname__ for nested class support."""
  34. self.assertEqual(repr(Nested.Field()), '<model_fields.tests.Nested.Field>')
  35. def test_field_name(self):
  36. """
  37. A defined field name (name="fieldname") is used instead of the model
  38. model's attribute name (modelname).
  39. """
  40. instance = RenamedField()
  41. self.assertTrue(hasattr(instance, 'get_fieldname_display'))
  42. self.assertFalse(hasattr(instance, 'get_modelname_display'))
  43. def test_field_verbose_name(self):
  44. m = VerboseNameField
  45. for i in range(1, 23):
  46. self.assertEqual(m._meta.get_field('field%d' % i).verbose_name, 'verbose field%d' % i)
  47. self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk')
  48. def test_choices_form_class(self):
  49. """Can supply a custom choices form class to Field.formfield()"""
  50. choices = [('a', 'a')]
  51. field = models.CharField(choices=choices)
  52. klass = forms.TypedMultipleChoiceField
  53. self.assertIsInstance(field.formfield(choices_form_class=klass), klass)
  54. def test_formfield_disabled(self):
  55. """Field.formfield() sets disabled for fields with choices."""
  56. field = models.CharField(choices=[('a', 'b')])
  57. form_field = field.formfield(disabled=True)
  58. self.assertIs(form_field.disabled, True)
  59. def test_field_str(self):
  60. f = models.Field()
  61. self.assertEqual(str(f), '<django.db.models.fields.Field>')
  62. f = Foo._meta.get_field('a')
  63. self.assertEqual(str(f), 'model_fields.Foo.a')
  64. def test_field_ordering(self):
  65. """Fields are ordered based on their creation."""
  66. f1 = models.Field()
  67. f2 = models.Field(auto_created=True)
  68. f3 = models.Field()
  69. self.assertLess(f2, f1)
  70. self.assertGreater(f3, f1)
  71. self.assertIsNotNone(f1)
  72. self.assertNotIn(f2, (None, 1, ''))
  73. def test_field_instance_is_picklable(self):
  74. """Field instances can be pickled."""
  75. field = models.Field(max_length=100, default='a string')
  76. # Must be picklable with this cached property populated (#28188).
  77. field._get_default
  78. pickle.dumps(field)
  79. def test_deconstruct_nested_field(self):
  80. """deconstruct() uses __qualname__ for nested class support."""
  81. name, path, args, kwargs = Nested.Field().deconstruct()
  82. self.assertEqual(path, 'model_fields.tests.Nested.Field')
  83. class ChoicesTests(SimpleTestCase):
  84. def test_choices_and_field_display(self):
  85. """
  86. get_choices() interacts with get_FIELD_display() to return the expected
  87. values.
  88. """
  89. self.assertEqual(Whiz(c=1).get_c_display(), 'First') # A nested value
  90. self.assertEqual(Whiz(c=0).get_c_display(), 'Other') # A top level value
  91. self.assertEqual(Whiz(c=9).get_c_display(), 9) # Invalid value
  92. self.assertIsNone(Whiz(c=None).get_c_display()) # Blank value
  93. self.assertEqual(Whiz(c='').get_c_display(), '') # Empty value
  94. def test_iterator_choices(self):
  95. """
  96. get_choices() works with Iterators.
  97. """
  98. self.assertEqual(WhizIter(c=1).c, 1) # A nested value
  99. self.assertEqual(WhizIter(c=9).c, 9) # Invalid value
  100. self.assertIsNone(WhizIter(c=None).c) # Blank value
  101. self.assertEqual(WhizIter(c='').c, '') # Empty value
  102. def test_empty_iterator_choices(self):
  103. """
  104. get_choices() works with empty iterators.
  105. """
  106. self.assertEqual(WhizIterEmpty(c="a").c, "a") # A nested value
  107. self.assertEqual(WhizIterEmpty(c="b").c, "b") # Invalid value
  108. self.assertIsNone(WhizIterEmpty(c=None).c) # Blank value
  109. self.assertEqual(WhizIterEmpty(c='').c, '') # Empty value
  110. class GetChoicesTests(SimpleTestCase):
  111. def test_blank_in_choices(self):
  112. choices = [('', '<><>'), ('a', 'A')]
  113. f = models.CharField(choices=choices)
  114. self.assertEqual(f.get_choices(include_blank=True), choices)
  115. def test_blank_in_grouped_choices(self):
  116. choices = [
  117. ('f', 'Foo'),
  118. ('b', 'Bar'),
  119. ('Group', (
  120. ('', 'No Preference'),
  121. ('fg', 'Foo'),
  122. ('bg', 'Bar'),
  123. )),
  124. ]
  125. f = models.CharField(choices=choices)
  126. self.assertEqual(f.get_choices(include_blank=True), choices)
  127. def test_lazy_strings_not_evaluated(self):
  128. lazy_func = lazy(lambda x: 0 / 0, int) # raises ZeroDivisionError if evaluated.
  129. f = models.CharField(choices=[(lazy_func('group'), (('a', 'A'), ('b', 'B')))])
  130. self.assertEqual(f.get_choices(include_blank=True)[0], ('', '---------'))
  131. class GetChoicesOrderingTests(TestCase):
  132. @classmethod
  133. def setUpTestData(cls):
  134. cls.foo1 = Foo.objects.create(a='a', d='12.34')
  135. cls.foo2 = Foo.objects.create(a='b', d='12.34')
  136. cls.bar1 = Bar.objects.create(a=cls.foo1, b='a')
  137. cls.bar2 = Bar.objects.create(a=cls.foo2, b='a')
  138. cls.field = Bar._meta.get_field('a')
  139. def assertChoicesEqual(self, choices, objs):
  140. self.assertEqual(choices, [(obj.pk, str(obj)) for obj in objs])
  141. def test_get_choices(self):
  142. self.assertChoicesEqual(
  143. self.field.get_choices(include_blank=False, ordering=('a',)),
  144. [self.foo1, self.foo2]
  145. )
  146. self.assertChoicesEqual(
  147. self.field.get_choices(include_blank=False, ordering=('-a',)),
  148. [self.foo2, self.foo1]
  149. )
  150. def test_get_choices_reverse_related_field(self):
  151. self.assertChoicesEqual(
  152. self.field.remote_field.get_choices(include_blank=False, ordering=('a',)),
  153. [self.bar1, self.bar2]
  154. )
  155. self.assertChoicesEqual(
  156. self.field.remote_field.get_choices(include_blank=False, ordering=('-a',)),
  157. [self.bar2, self.bar1]
  158. )