parts/django/tests/regressiontests/inline_formsets/tests.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 from django.forms.models import inlineformset_factory
       
     2 from django.test import TestCase
       
     3 
       
     4 from regressiontests.inline_formsets.models import Poet, Poem, School, Parent, Child
       
     5 
       
     6 
       
     7 class 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         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': u'1',
       
    68             'poem_set-0-poem': u'1',
       
    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 
       
   110 class InlineFormsetFactoryTest(TestCase):
       
   111     def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
       
   112         self.assertRaises(error, callable, *args, **kwargs)
       
   113         try:
       
   114             callable(*args, **kwargs)
       
   115         except error, e:
       
   116             self.assertEqual(message, str(e))
       
   117 
       
   118     def test_inline_formset_factory(self):
       
   119         """
       
   120         These should both work without a problem.
       
   121         """
       
   122         inlineformset_factory(Parent, Child, fk_name='mother')
       
   123         inlineformset_factory(Parent, Child, fk_name='father')
       
   124 
       
   125     def test_exception_on_unspecified_foreign_key(self):
       
   126         """
       
   127         Child has two ForeignKeys to Parent, so if we don't specify which one
       
   128         to use for the inline formset, we should get an exception.
       
   129         """
       
   130         self.assertRaisesErrorWithMessage(Exception,
       
   131             "<class 'regressiontests.inline_formsets.models.Child'> has more than 1 ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
       
   132             inlineformset_factory, Parent, Child
       
   133         )
       
   134 
       
   135     def test_fk_name_not_foreign_key_field_from_child(self):
       
   136         """
       
   137         If we specify fk_name, but it isn't a ForeignKey from the child model
       
   138         to the parent model, we should get an exception.
       
   139         """
       
   140         self.assertRaisesErrorWithMessage(Exception,
       
   141             "fk_name 'school' is not a ForeignKey to <class 'regressiontests.inline_formsets.models.Parent'>",
       
   142             inlineformset_factory, Parent, Child, fk_name='school'
       
   143         )
       
   144 
       
   145     def test_non_foreign_key_field(self):
       
   146         """
       
   147         If the field specified in fk_name is not a ForeignKey, we should get an
       
   148         exception.
       
   149         """
       
   150         self.assertRaisesErrorWithMessage(Exception,
       
   151             "<class 'regressiontests.inline_formsets.models.Child'> has no field named 'test'",
       
   152             inlineformset_factory, Parent, Child, fk_name='test'
       
   153         )
       
   154 
       
   155     def test_any_iterable_allowed_as_argument_to_exclude(self):
       
   156         # Regression test for #9171.
       
   157         inlineformset_factory(
       
   158             Parent, Child, exclude=['school'], fk_name='mother'
       
   159         )
       
   160 
       
   161         inlineformset_factory(
       
   162             Parent, Child, exclude=('school',), fk_name='mother'
       
   163         )