diff --git a/django_object_actions/templates/django_object_actions/action_trigger.html b/django_object_actions/templates/django_object_actions/action_trigger.html new file mode 100644 index 0000000..34e1587 --- /dev/null +++ b/django_object_actions/templates/django_object_actions/action_trigger.html @@ -0,0 +1,22 @@ +{% load add_preserved_filters from admin_urls %} + +{% if tool.button_type == 'a' %} + {{ tool.label|capfirst }} +{% elif tool.button_type == 'form' %} +
+ {% csrf_token %} + {{ tool.label|capfirst }} +
+{% endif %} diff --git a/django_object_actions/templates/django_object_actions/change_form.html b/django_object_actions/templates/django_object_actions/change_form.html index 1b0f80d..e5457d8 100644 --- a/django_object_actions/templates/django_object_actions/change_form.html +++ b/django_object_actions/templates/django_object_actions/change_form.html @@ -1,17 +1,10 @@ {% extends "admin/change_form.html" %} -{% load add_preserved_filters from admin_urls %} {% block object-tools-items %} {% for tool in objectactions %}
  • {% url tools_view_name pk=object_id tool=tool.name as action_url %} - - {{ tool.label|capfirst }} - + {% include 'django_object_actions/action_trigger.html' %}
  • {% endfor %} {{ block.super }} diff --git a/django_object_actions/templates/django_object_actions/change_list.html b/django_object_actions/templates/django_object_actions/change_list.html index 2fd9082..2d91eff 100644 --- a/django_object_actions/templates/django_object_actions/change_list.html +++ b/django_object_actions/templates/django_object_actions/change_list.html @@ -1,17 +1,10 @@ {% extends "admin/change_list.html" %} -{% load add_preserved_filters from admin_urls %} {% block object-tools-items %} {% for tool in objectactions %}
  • {% url tools_view_name tool=tool.name as action_url %} - - {{ tool.label|capfirst }} - + {% include 'django_object_actions/action_trigger.html' %}
  • {% endfor %} {{ block.super }} diff --git a/django_object_actions/utils.py b/django_object_actions/utils.py index 92ada06..6bd3b60 100644 --- a/django_object_actions/utils.py +++ b/django_object_actions/utils.py @@ -5,7 +5,7 @@ from django.contrib.admin.utils import unquote from django.db.models.query import QuerySet from django.http import Http404, HttpResponseRedirect -from django.http.response import HttpResponseBase +from django.http.response import HttpResponseBase, HttpResponseNotAllowed from django.views.generic import View from django.views.generic.detail import SingleObjectMixin from django.views.generic.list import MultipleObjectMixin @@ -159,6 +159,7 @@ def _get_tool_dict(self, tool_name): label=getattr(tool, "label", tool_name.replace("_", " ").capitalize()), standard_attrs=standard_attrs, custom_attrs=custom_attrs, + button_type=tool.button_type, ) def _get_button_attrs(self, tool): @@ -238,7 +239,7 @@ def back_url(self): """ raise NotImplementedError - def get(self, request, tool, **kwargs): + def dispatch(self, request, tool, **kwargs): # Fix for case if there are special symbols in object pk for k, v in self.kwargs.items(): self.kwargs[k] = unquote(v) @@ -248,15 +249,15 @@ def get(self, request, tool, **kwargs): except KeyError: raise Http404("Action does not exist") + if request.method not in view.methods: + return HttpResponseNotAllowed(view.methods) + ret = view(request, *self.view_args) if isinstance(ret, HttpResponseBase): return ret return HttpResponseRedirect(self.back_url) - # HACK to allow POST requests too - post = get - def message_user(self, request, message): """ Mimic Django admin actions's `message_user`. @@ -314,7 +315,9 @@ def decorated_function(self, request, queryset): def action( - function=None, *, permissions=None, description=None, label=None, attrs=None + function=None, *, permissions=None, description=None, label=None, attrs=None, + methods=('GET', 'POST'), + button_type='a', ): """ Conveniently add attributes to an action function: @@ -349,6 +352,8 @@ def decorator(func): func.label = label if attrs is not None: func.attrs = attrs + func.methods = methods + func.button_type = button_type return func if function is None: