tests.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. from django.forms.models import inlineformset_factory
  2. from django.test import TestCase
  3. from regressiontests.inline_formsets.models import Poet, Poem, School, Parent, Child
  4. class DeletionTests(TestCase):
  5. def test_deletion(self):
  6. PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
  7. poet = Poet.objects.create(name='test')
  8. poem = poet.poem_set.create(name='test poem')
  9. data = {
  10. 'poem_set-TOTAL_FORMS': u'1',
  11. 'poem_set-INITIAL_FORMS': u'1',
  12. 'poem_set-MAX_NUM_FORMS': u'0',
  13. 'poem_set-0-id': str(poem.pk),
  14. 'poem_set-0-poet': str(poet.pk),
  15. 'poem_set-0-name': u'test',
  16. 'poem_set-0-DELETE': u'on',
  17. }
  18. formset = PoemFormSet(data, instance=poet)
  19. formset.save()
  20. self.assertTrue(formset.is_valid())
  21. self.assertEqual(Poem.objects.count(), 0)
  22. def test_add_form_deletion_when_invalid(self):
  23. """
  24. Make sure that an add form that is filled out, but marked for deletion
  25. doesn't cause validation errors.
  26. """
  27. PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
  28. poet = Poet.objects.create(name='test')
  29. data = {
  30. 'poem_set-TOTAL_FORMS': u'1',
  31. 'poem_set-INITIAL_FORMS': u'0',
  32. 'poem_set-MAX_NUM_FORMS': u'0',
  33. 'poem_set-0-id': u'',
  34. 'poem_set-0-poem': u'1',
  35. 'poem_set-0-name': u'x' * 1000,
  36. }
  37. formset = PoemFormSet(data, instance=poet)
  38. # Make sure this form doesn't pass validation.
  39. self.assertEqual(formset.is_valid(), False)
  40. self.assertEqual(Poem.objects.count(), 0)
  41. # Then make sure that it *does* pass validation and delete the object,
  42. # even though the data isn't actually valid.
  43. data['poem_set-0-DELETE'] = 'on'
  44. formset = PoemFormSet(data, instance=poet)
  45. self.assertEqual(formset.is_valid(), True)
  46. formset.save()
  47. self.assertEqual(Poem.objects.count(), 0)
  48. def test_change_form_deletion_when_invalid(self):
  49. """
  50. Make sure that a change form that is filled out, but marked for deletion
  51. doesn't cause validation errors.
  52. """
  53. PoemFormSet = inlineformset_factory(Poet, Poem, can_delete=True)
  54. poet = Poet.objects.create(name='test')
  55. poem = poet.poem_set.create(name='test poem')
  56. data = {
  57. 'poem_set-TOTAL_FORMS': u'1',
  58. 'poem_set-INITIAL_FORMS': u'1',
  59. 'poem_set-MAX_NUM_FORMS': u'0',
  60. 'poem_set-0-id': unicode(poem.id),
  61. 'poem_set-0-poem': unicode(poem.id),
  62. 'poem_set-0-name': u'x' * 1000,
  63. }
  64. formset = PoemFormSet(data, instance=poet)
  65. # Make sure this form doesn't pass validation.
  66. self.assertEqual(formset.is_valid(), False)
  67. self.assertEqual(Poem.objects.count(), 1)
  68. # Then make sure that it *does* pass validation and delete the object,
  69. # even though the data isn't actually valid.
  70. data['poem_set-0-DELETE'] = 'on'
  71. formset = PoemFormSet(data, instance=poet)
  72. self.assertEqual(formset.is_valid(), True)
  73. formset.save()
  74. self.assertEqual(Poem.objects.count(), 0)
  75. def test_save_new(self):
  76. """
  77. Make sure inlineformsets respect commit=False
  78. regression for #10750
  79. """
  80. # exclude some required field from the forms
  81. ChildFormSet = inlineformset_factory(School, Child, exclude=['father', 'mother'])
  82. school = School.objects.create(name=u'test')
  83. mother = Parent.objects.create(name=u'mother')
  84. father = Parent.objects.create(name=u'father')
  85. data = {
  86. 'child_set-TOTAL_FORMS': u'1',
  87. 'child_set-INITIAL_FORMS': u'0',
  88. 'child_set-MAX_NUM_FORMS': u'0',
  89. 'child_set-0-name': u'child',
  90. }
  91. formset = ChildFormSet(data, instance=school)
  92. self.assertEqual(formset.is_valid(), True)
  93. objects = formset.save(commit=False)
  94. for obj in objects:
  95. obj.mother = mother
  96. obj.father = father
  97. obj.save()
  98. self.assertEqual(school.child_set.count(), 1)
  99. class InlineFormsetFactoryTest(TestCase):
  100. def test_inline_formset_factory(self):
  101. """
  102. These should both work without a problem.
  103. """
  104. inlineformset_factory(Parent, Child, fk_name='mother')
  105. inlineformset_factory(Parent, Child, fk_name='father')
  106. def test_exception_on_unspecified_foreign_key(self):
  107. """
  108. Child has two ForeignKeys to Parent, so if we don't specify which one
  109. to use for the inline formset, we should get an exception.
  110. """
  111. self.assertRaisesRegexp(Exception,
  112. "<class 'regressiontests.inline_formsets.models.Child'> has more than 1 ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
  113. inlineformset_factory, Parent, Child
  114. )
  115. def test_fk_name_not_foreign_key_field_from_child(self):
  116. """
  117. If we specify fk_name, but it isn't a ForeignKey from the child model
  118. to the parent model, we should get an exception.
  119. """
  120. self.assertRaises(Exception,
  121. "fk_name 'school' is not a ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
  122. inlineformset_factory, Parent, Child, fk_name='school'
  123. )
  124. def test_non_foreign_key_field(self):
  125. """
  126. If the field specified in fk_name is not a ForeignKey, we should get an
  127. exception.
  128. """
  129. self.assertRaisesRegexp(Exception,
  130. "<class 'regressiontests.inline_formsets.models.Child'> has no field named 'test'",
  131. inlineformset_factory, Parent, Child, fk_name='test'
  132. )
  133. def test_any_iterable_allowed_as_argument_to_exclude(self):
  134. # Regression test for #9171.
  135. inlineformset_factory(
  136. Parent, Child, exclude=['school'], fk_name='mother'
  137. )
  138. inlineformset_factory(
  139. Parent, Child, exclude=('school',), fk_name='mother'
  140. )