#6406 closed (duplicate)
form_save_add and form_save_change method for ModelAdmin
| Reported by: | Michel Sabchuk | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.admin | Version: | newforms-admin |
| Severity: | Keywords: | form object save commit | |
| Cc: | michelts@…, bpederse@…, cmawebsite@… | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | UI/UX: |
Description
ModelAdmin calls form.save() inside the save_add method:
def save_add(self, request, model, form, formsets, post_url_continue):
...
new_object = form.save(commit=True)
if formsets:
for formset in formsets:
formset.instance = new_object
formset.save()
pk_value = new_object._get_pk_val()
...
I want to be able to hack the form.save method and calculate aditional data to the object based on the request. Basically, I want to attach the request.user to an attribute of my just added object. I have a solution, I can call a save_form_add method of ModelAdmin that saves the form:
def save_add(self, request, model, form, formsets, post_url_continue):
...
new_object = self.save_form_add(request, model, form, formsets, post_url_continue)
pk_value = new_object._get_pk_val()
...
def save_form_add(self, request, model, form, formsets, post_url_continue):
new_object = form.save(commit=True)
if formsets:
for formset in formsets:
formset.instance = new_object
formset.save()
return new_object
This way I can do something like this:
class ObjectOptions(admin.ModelAdmin):
def form_save_add(self, request, model, form, formsets, post_url_continue):
new_object = form.save(commit=False)
new_object.user = request.user
new_object.save()
if formsets:
for formset in formsets:
formset.instance = new_object
formset.save()
return new_object
I didn´t find any other solution to intercept the object save and have access to the request.
What do you think about the addition of save_form_add and save_form_change? I will write the proper patch.
Best regards!
Attachments (2)
Change History (13)
comment:1 by , 18 years ago
| Keywords: | nfa-blocker added |
|---|---|
| Triage Stage: | Unreviewed → Design decision needed |
by , 18 years ago
| Attachment: | form_save_hooks.diff added |
|---|
Ok, this is a fairly simple implementation, if this is not what was intended let me know so I can fix it, fair simple/
comment:2 by , 17 years ago
What I understand. This is probably a duplicate of #6002 as 6002 is more generic and provides more hooks. BTW...is this issue heading anywhere? I see this as an important feature. Copying the whole save_add/change method to my Admin options class is a terrible waste.
comment:3 by , 17 years ago
| milestone: | → 1.0 alpha |
|---|
comment:4 by , 17 years ago
Replying to michelts:
I think it is better to factor two smaller methods:
def _save_form(self, request, model, form, commit=True) :
return form.save(commit=commit)
def _save_formset(self, request, model, formset) :
return formset.save()
This way one doesn't need to repeat the formsets loop when one wants to add an attribute to form. I'll attach a patch for this.
by , 17 years ago
| Attachment: | admin_options.diff added |
|---|
Factor _save_form and _save_formset from save_add and save_change.
comment:5 by , 17 years ago
| Cc: | added |
|---|
comment:6 by , 17 years ago
| Cc: | added |
|---|
comment:7 by , 17 years ago
| Keywords: | nfa-blocker removed |
|---|---|
| milestone: | 1.0 alpha → 1.0 beta |
This actually really isn't critical for a merge. I am going to drop the nfa-blocker and bump to 1.0 beta. I will look at it later.
comment:8 by , 17 years ago
Some other approaches have been proposed in #8005. Not sure which ticket should be considered most in this regard.
comment:9 by , 17 years ago
| Triage Stage: | Design decision needed → Accepted |
|---|
comment:10 by , 17 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
I see what you are trying to accomplish and it can be accomplished by overriding
save_addandsave_changebased on what you are trying to do. However, both of those methods are doing alot. I feel this stuff needs to be encapsulated in its own that is then worked with in the view. I will begin to think about this a bit more. Basically it needs to be handled one level higher than this.