Fixed #16869 -- BaseGenericInlineFormSet.save_new should use form's save() method

Thanks mattaustin for the report and Pablo Recio (pyriku) for the patch.
This commit is contained in:
Pablo Mouzo 2013-09-07 15:58:32 -05:00 committed by Tim Graham
parent c348550d35
commit b11564fd36
2 changed files with 32 additions and 7 deletions

View File

@ -415,13 +415,12 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
)) ))
def save_new(self, form, commit=True): def save_new(self, form, commit=True):
kwargs = { setattr(form.instance, self.ct_field.get_attname(),
self.ct_field.get_attname(): ContentType.objects.get_for_model( ContentType.objects.get_for_model(self.instance).pk)
self.instance, for_concrete_model=self.for_concrete_model).pk, setattr(form.instance, self.ct_fk_field.get_attname(),
self.ct_fk_field.get_attname(): self.instance.pk, self.instance.pk)
} return form.save(commit=commit)
new_obj = self.model(**kwargs)
return save_instance(form, new_obj, commit=commit)
def generic_inlineformset_factory(model, form=ModelForm, def generic_inlineformset_factory(model, form=ModelForm,
formset=BaseGenericInlineFormSet, formset=BaseGenericInlineFormSet,

View File

@ -306,6 +306,32 @@ class GenericInlineFormsetTest(TestCase):
form = Formset().forms[0] form = Formset().forms[0]
self.assertIsInstance(form['tag'].field.widget, CustomWidget) 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): def test_save_new_for_proxy(self):
Formset = generic_inlineformset_factory(ForProxyModelModel, Formset = generic_inlineformset_factory(ForProxyModelModel,
fields='__all__', for_concrete_model=False) fields='__all__', for_concrete_model=False)