So right now you can add simple admin actions “easily”:
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
...
actions = ["do_something"]
@admin.action(description="Do A Thing")
def do_something(self, request, queryset): ...
This is great for simple thing where you can just choose stuff. But the moment you need to collect more information than what instances to operate on, Django kinda bails on you, telling you stuff like “well pass the PKs as GET params to your own custom view and do stuff”.
Idea that I think makes sense: an AdminAction
class that can do the following:
- provide an action like the existing actions
- optionally provide a form that, if present, is used for an intermediate view to collect more info before actually doing the action
For example:
class ExtraDataForm(Form):
low_priority = BooleanField()
class DoThing(AdminAction):
form_class = ExtraDataForm
label = "Do Thing"
url_slug = "do-thing"
def perform_action(self, request, queryset, form):
# only called if form.is_valid()
if form.validated_data['low_priority']:
...
else:
...
class TagAdmin(ModelAdmin):
actions = [DoThing]
In the above example (roughly), when we pick the “Do Thing” action, we first get redirected to an intermediate view that shows us the form (and also has the admin submitted selections in a hidden form). Once submitting successfully there, we perform the action.
A “fluid” version of this would be for the form to actually appear in the admin list view directly, instead of on a separate page. For example, if you pick “Do Thing” in the action dropdown, it inline displays a form that needs to be filled out properly, right there.
^ imagine if in the above, under “Do A Thing” you just embedded a form.
This is mostly a sketch of an idea, but I do think it should be more straightforward to add a bit of extra data alongside admin actions.