Code

Opened 7 years ago

Closed 5 years ago

#4507 closed (fixed)

Adding form save hooks to newforms admin

Reported by: Stas Shtin <antisvin@…> Owned by: nobody
Component: contrib.admin Version: newforms-admin
Severity: Keywords: nfa-someday
Cc: Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Sometimes it's necessary to set DB fields bypassing user input with values based on request object or state of the world. Specific use cases would be saving object creator, last editor, expiration date (i.e. current date + some period of time).
I haven't found any other way for setting DB fields that are not editable with admin application.

Also please notice that ticket #4312 has the same motives as this one, but targeting form_for_model and form_for_instance. Accepting that one would make overloading form save hooks even easier.

Attachments (2)

newforms-admin-form-save-hooks.diff (1.9 KB) - added by Stas Shtin <antisvin@…> 7 years ago.
model-admin-save-hooks.diff (2.6 KB) - added by Petr Marhoun <petr.marhoun@…> 7 years ago.

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by Stas Shtin <antisvin@…>

comment:1 Changed 7 years ago by SmileyChris

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

See #4727 for another solution to this.

comment:2 Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

I don't think that #4727 solves this problem. If I have model MyModel and base form MyBaseForm, then the method resolution order is:

(<class 'django.newforms.widgets.MyModelForm'>, <class 'my_project.my_app.MyBaseFrom'>, <class 'django.newforms.forms.BaseForm'>, <class 'django.utils.encoding.StrAndUnicode'>, <type 'object'>)

Method django.newforms.widgets.MyModelForm.save is in reality function django.newforms.models.save_instance - save method in MyBaseForm is not called.

Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

comment:3 Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

The attached patch is compatible with the current branch and has more arguments.

comment:4 Changed 7 years ago by Petr Marhoun <petr.marhoun@…>

I have two real examples where I need this hook and I don't think that it can be solved with base forms. (All names are changed.)

  1. ParentModel has three child models - ChildModelOne, ChildModelTwo and ChildModelThree. Instances of ChildModelOne and ChildModelTwo are edited by users as inlines. Instances of ChildModelThree are generated from saved instances of ParentModel, ChildModelOne and ChildModelTwo. My code is:
class MyModelOptions(admin.ModelAdmin):
    # ...

    def form_save(self, request, model, form, formsets, commit, add):
        my_object = super(MyModelOptions, self).form_save(request, model, form,
            formsets, commit, add)
        my_object.generate_instances_of_child_model_three()
        return my_object

  1. Second example is the same as in the original description. So I only show my code:
class MyModelOptions(admin.ModelAdmin):
    # ...

    base_form = MyModelBaseForm

    def form_save(self, request, model, form, formsets, commit, add):
        my_object = super(MyModelOptions, self).form_save(request, model, form,
            formsets, False, add)
        my_object.set_other_data(form.other_data)
        my_object.save()
        form.save_m2m()
        return my_object

I use save hook and base form - I need both.

comment:5 Changed 6 years ago by Karen Tracey <kmtracey@…>

  • Keywords nfa-someday added

Near as I can tell this is request for new function that wasn't available in old admin either? As such it should not block newforms-admin merge. If I'm wrong feel free to correct me.

comment:6 Changed 6 years ago by brosner

The real solution to this would be with ModelForm. Once newforms-admin uses it instead of the form_for_* functions then it should be made override-able and then you can change the save behavior.

comment:7 Changed 5 years ago by jkocherhans

  • Resolution set to fixed
  • Status changed from new to closed

This has been fixed at some point. See save_form, save_model, and save_formset on the ModelAdmin class.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.