Skip to content

Commit

Permalink
add test coverage and example of a POST only tool
Browse files Browse the repository at this point in the history
  • Loading branch information
crccheck committed Sep 9, 2024
1 parent 37d56e1 commit 96c5fe6
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 9 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,12 @@ preferable that actions use a HTTP POST instead of a GET.
You can configure an action to only use POST with:

```python
@action(methods=("post",), button_type="form")
@action(methods=("POST",), button_type="form")
```

One caveat is Django's styling is pinned to anchor tags[^1], so to maintain visual
consistency with other actions, we have to use anchor tags too.
One caveat is Django's styling is pinned to anchor tags[^1], so to maintain
visual consistency with other actions, we have to use anchor tags too and use
JavaScript to turn make it act like a form.

[^1]: https://github.com/django/django/blob/826ef006681eae1e9b4bd0e4f18fa13713025cba/django/contrib/admin/static/admin/css/base.css#L786

Expand Down Expand Up @@ -267,4 +268,3 @@ open a simple form in a modal dialog.

If you want an actions menu for each row of your changelist, check out [Django
Admin Row Actions](https://github.com/DjangoAdminHackers/django-admin-row-actions).

14 changes: 13 additions & 1 deletion django_object_actions/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,22 @@ def test_changelist_template_context(self):
self.assertIn("foo", response.context_data)

def test_changelist_action_view(self):
url = "/admin/polls/choice/actions/delete_all/"
url = reverse("admin:polls_choice_actions", args=("delete_all",))
response = self.client.get(url)
self.assertRedirects(response, "/admin/polls/choice/")

def test_changelist_action_post_only_tool_rejects_get(self):
poll = PollFactory.create()
url = reverse(
"admin:polls_choice_actions",
args=(
poll.pk,
"reset_vote",
),
)
response = self.client.get(url)
self.assertEqual(response.status_code, 405)

def test_changelist_nonexistent_action(self):
url = "/admin/polls/choice/actions/xyzzy/"
response = self.client.get(url)
Expand Down
1 change: 1 addition & 0 deletions django_object_actions/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def test_can_return_template(self):
# it's good to document that this is something we can do.
url = reverse("admin:polls_poll_actions", args=(1, "delete_all_choices"))
response = self.client.get(url)
print(url, response)
self.assertTemplateUsed(response, "clear_choices.html")

def test_message_user_sends_message(self):
Expand Down
8 changes: 5 additions & 3 deletions django_object_actions/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ class BaseActionView(View):
model = None
actions = None
current_app = None
methods = ("GET", "POST")

@property
def view_args(self):
Expand Down Expand Up @@ -250,8 +249,11 @@ def dispatch(self, request, tool, **kwargs):
except KeyError:
raise Http404("Action does not exist")

if request.method not in self.methods:
return HttpResponseNotAllowed(view.methods)
# TODO move ('get', 'post' config default someplace else)
allowed_methods = getattr(view, "methods", ("GET", "POST"))
print("dispatch", request.method, allowed_methods)
if request.method.upper() not in allowed_methods:
return HttpResponseNotAllowed(allowed_methods)

ret = view(request, *self.view_args)
if isinstance(ret, HttpResponseBase):
Expand Down
2 changes: 1 addition & 1 deletion example_project/polls/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def decrement_vote(self, request, obj):
def delete_all(self, request, queryset):
self.message_user(request, "just kidding!")

@action(description="0")
@action(description="0", methods=("POST",), button_type="form")
def reset_vote(self, request, obj):
obj.votes = 0
obj.save()
Expand Down

0 comments on commit 96c5fe6

Please sign in to comment.