Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django admin overriding save method at inlines?

Is there a way to override the save method for inlines form and parent at the same time?

I would like to change the value of a field when the user saves the edited inline form.

Thanks :)

like image 340
Asinox Avatar asked Sep 03 '09 23:09

Asinox


1 Answers

To customize the saving of inlines, you can override the FormSet

class SomeInlineFormSet(BaseInlineFormSet):
    def save_new(self, form, commit=True):
        return super(SomeInlineFormSet, self).save_new(form, commit=commit)

    def save_existing(self, form, instance, commit=True):
        return form.save(commit=commit)

class SomeInline(admin.StackedInline):
    formset = SomeInlineFormSet
    # ....

Note that the save_new() only uses the form to get the data, it does not let the ModelForm commit the data. Instead, it constructs the model itself. This allows it to insert the parent relation since they don't exist in the form. That's why overriding form.save() does not work.

In the case of generic inlines, the form.save() method is never called, and form.cleaned_data is used instead to get all values, and Field.save_form_data() is used to store the values in the model instance.


FYI, some general tip to figure these kind of things out; it's really valuable to have an IDE (or maybe vim config or Sublime setup) that allows to jump to symbol definitions really easily. The code above was figured out by jumping into the inline/formset code, and see what is happening. In the case of PyCharm, that works by holding Command (or Ctrl), and clicking on the symbol. If you're a vim user, ctags might be able to do a similar thing for you.

like image 68
vdboor Avatar answered Oct 14 '22 15:10

vdboor