|
4 | 4 | from django.contrib import messages
|
5 | 5 | from django.contrib.admin.utils import unquote
|
6 | 6 | from django.db.models.query import QuerySet
|
| 7 | +from django.forms import Form |
7 | 8 | from django.http import Http404, HttpResponseRedirect
|
8 | 9 | from django.http.response import HttpResponseBase
|
9 | 10 | from django.views.generic import View
|
@@ -159,6 +160,7 @@ def _get_tool_dict(self, tool_name):
|
159 | 160 | label=getattr(tool, "label", tool_name.replace("_", " ").capitalize()),
|
160 | 161 | standard_attrs=standard_attrs,
|
161 | 162 | custom_attrs=custom_attrs,
|
| 163 | + form=self._get_form(tool), |
162 | 164 | )
|
163 | 165 |
|
164 | 166 | def _get_button_attrs(self, tool):
|
@@ -192,6 +194,12 @@ def _get_button_attrs(self, tool):
|
192 | 194 | custom_attrs[k] = v
|
193 | 195 | return standard_attrs, custom_attrs
|
194 | 196 |
|
| 197 | + def _get_form(self, tool): |
| 198 | + form = getattr(tool, "form", None) |
| 199 | + if callable(form) and not isinstance(form, Form): |
| 200 | + form = form() |
| 201 | + return form |
| 202 | + |
195 | 203 |
|
196 | 204 | class DjangoObjectActions(BaseDjangoObjectActions):
|
197 | 205 | change_form_template = "django_object_actions/change_form.html"
|
@@ -311,7 +319,7 @@ def decorated_function(self, request, queryset):
|
311 | 319 |
|
312 | 320 |
|
313 | 321 | def action(
|
314 |
| - function=None, *, permissions=None, description=None, label=None, attrs=None |
| 322 | + function=None, *, permissions=None, description=None, label=None, attrs=None, form=None |
315 | 323 | ):
|
316 | 324 | """
|
317 | 325 | Conveniently add attributes to an action function::
|
@@ -347,6 +355,8 @@ def decorator(func):
|
347 | 355 | func.label = label
|
348 | 356 | if attrs is not None:
|
349 | 357 | func.attrs = attrs
|
| 358 | + if form is not None: |
| 359 | + func.form = form |
350 | 360 | return func
|
351 | 361 |
|
352 | 362 | if function is None:
|
|
0 commit comments