Opened 2 years ago

Last modified 2 years ago

#25387 new New feature

ModelAdmin actions don't get access to the ActionForm

Reported by: Malcolm Box Owned by: nobody
Component: contrib.admin Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Setting an alternative ModelAdmin.action_form is supported, but ModelAdmin.actions don't get access to the form.

The naive approach is to rebind the form in the action:

class ExampleAdmin(admin.ModelAdmin):
     action_form = ExampleForm
     actions = ['example_action']
 
     def example_action(self, request, queryset):
         form = ExampleForm(request.POST)
         if form.is_valid():
             # Process...

However, this doesn't work (form.is_valid() returns False) because there's special processing done on the request.DATA before the form is bound - see https://github.com/django/django/blob/master/django/contrib/admin/options.py#L1205-L1220

So either this code has to be duplicated in the action, or the request.POST data processed manually. Neither seem ideal.

A proposed fix would be to make the action_form that's bound in options.py be available as self.bound_action_form so that actions could access it. This would be entirely backwards-compatible.

Change History (1)

comment:1 Changed 2 years ago by Tim Graham

Triage Stage: UnreviewedAccepted
Type: BugNew feature

While I see the simplicity of self.bound_action_form from a backwards compatibility standpoint, I don't think storing state on the ModelAdmin class is thread-safe.

It seems cleaner if the action view were passed action_form. A backwards compatibility shim could be added similar to what was done in a7c256cb5491bf2a77abdff01638239db5bfd9d5 to support both forms of the action view for a deprecation period.

Note: See TracTickets for help on using tickets.
Back to Top