From b11564fd36587b1077bf7d77b62b7879cc08c382 Mon Sep 17 00:00:00 2001 From: Pablo Mouzo Date: Sat, 7 Sep 2013 15:58:32 -0500 Subject: [PATCH] Fixed #16869 -- BaseGenericInlineFormSet.save_new should use form's save() method Thanks mattaustin for the report and Pablo Recio (pyriku) for the patch. --- django/contrib/contenttypes/generic.py | 13 ++++++------- tests/generic_relations/tests.py | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index 186f39068d..9db672c8a3 100644 --- a/django/contrib/contenttypes/generic.py +++ b/django/contrib/contenttypes/generic.py @@ -415,13 +415,12 @@ class BaseGenericInlineFormSet(BaseModelFormSet): )) def save_new(self, form, commit=True): - kwargs = { - self.ct_field.get_attname(): ContentType.objects.get_for_model( - self.instance, for_concrete_model=self.for_concrete_model).pk, - self.ct_fk_field.get_attname(): self.instance.pk, - } - new_obj = self.model(**kwargs) - return save_instance(form, new_obj, commit=commit) + setattr(form.instance, self.ct_field.get_attname(), + ContentType.objects.get_for_model(self.instance).pk) + setattr(form.instance, self.ct_fk_field.get_attname(), + self.instance.pk) + return form.save(commit=commit) + def generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, diff --git a/tests/generic_relations/tests.py b/tests/generic_relations/tests.py index 253eb76e32..dde00ccc8a 100644 --- a/tests/generic_relations/tests.py +++ b/tests/generic_relations/tests.py @@ -306,6 +306,32 @@ class GenericInlineFormsetTest(TestCase): form = Formset().forms[0] self.assertIsInstance(form['tag'].field.widget, CustomWidget) + def test_save_new_uses_form_save(self): + """ + Regression for #16260: save_new should call form.save() + """ + class SaveTestForm(forms.ModelForm): + def save(self, *args, **kwargs): + self.instance.saved_by = "custom method" + return super(SaveTestForm, self).save(*args, **kwargs) + + Formset = generic_inlineformset_factory( + ForProxyModelModel, fields='__all__', form=SaveTestForm) + + instance = ProxyRelatedModel.objects.create() + + data = { + 'form-TOTAL_FORMS': '1', + 'form-INITIAL_FORMS': '0', + 'form-MAX_NUM_FORMS': '', + 'form-0-title': 'foo', + } + + formset = Formset(data, instance=instance, prefix='form') + self.assertTrue(formset.is_valid()) + new_obj = formset.save()[0] + self.assertEqual(new_obj.saved_by, "custom method") + def test_save_new_for_proxy(self): Formset = generic_inlineformset_factory(ForProxyModelModel, fields='__all__', for_concrete_model=False)