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