Skip to content

Commit

Permalink
Update documentation and example project
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexerson committed Oct 27, 2022
1 parent c61d809 commit 425b4b6
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 23 deletions.
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ our templates.
In your admin.py:

```python
from django_object_actions import DjangoObjectActions
from django_object_actions import DjangoObjectActions, action

class ArticleAdmin(DjangoObjectActions, admin.ModelAdmin):
@action(label="Publish", description="Submit this article") # optional
def publish_this(self, request, obj):
publish_obj(obj)
publish_this.label = "Publish" # optional
publish_this.short_description = "Submit this article" # optional

change_actions = ('publish_this', )
```
Expand All @@ -49,10 +48,13 @@ views too. There, you'll get a queryset like a regular [admin action][admin acti
from django_object_actions import DjangoObjectActions

class MyModelAdmin(DjangoObjectActions, admin.ModelAdmin):

@action(
label="This will be the label of the button", # optional
description="This will be the tooltip of the button" # optional
)
def toolfunc(self, request, obj):
pass
toolfunc.label = "This will be the label of the button" # optional
toolfunc.short_description = "This will be the tooltip of the button" # optional

def make_published(modeladmin, request, queryset):
queryset.update(status='p')
Expand Down Expand Up @@ -92,9 +94,17 @@ class RobotAdmin(DjangoObjectActions, admin.ModelAdmin):
[admin actions]: https://docs.djangoproject.com/en/stable/ref/contrib/admin/actions/

### Customizing *Object Actions*
To give the action some a helpful title tooltip,

To give the action some a helpful title tooltip, add a
`short_description` attribute, similar to how admin actions work:
```python
@action(description="Increment the vote count by one")
def increment_vote(self, request, obj):
obj.votes = obj.votes + 1
obj.save()
```

Alternatively, you can also add a `short_description` attribute,
similar to how admin actions work:

```python
def increment_vote(self, request, obj):
Expand All @@ -107,6 +117,15 @@ By default, Django Object Actions will guess what to label the button
based on the name of the function. You can override this with a `label`
attribute:

```python
@action(label="Vote++")
def increment_vote(self, request, obj):
obj.votes = obj.votes + 1
obj.save()
```

or

```python
def increment_vote(self, request, obj):
obj.votes = obj.votes + 1
Expand All @@ -119,6 +138,15 @@ by adding a Django widget style
[attrs](https://docs.djangoproject.com/en/stable/ref/forms/widgets/#django.forms.Widget.attrs)
attribute:

```python
@action(attrs = {'class': 'addlink'})
def increment_vote(self, request, obj):
obj.votes = obj.votes + 1
obj.save()
```

or

```python
def increment_vote(self, request, obj):
obj.votes = obj.votes + 1
Expand Down
14 changes: 14 additions & 0 deletions django_object_actions/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ def action_2(modeladmin, request, queryset):
def action_3(modeladmin, request, queryset):
pass

@action(
attrs={
"class": "addlink",
}
)
def action_4(modeladmin, request, queryset):
pass

self.assertEqual(action_1.short_description, "First action of this admin site.")
self.assertEqual(action_2.allowed_permissions, ["do_action2"])
self.assertEqual(action_3.label, "Third action")
self.assertEqual(
action_4,
{
"class": "addlink",
},
)
6 changes: 5 additions & 1 deletion django_object_actions/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,9 @@ def decorated_function(self, request, queryset):
return decorated_function


def action(function=None, *, permissions=None, description=None, label=None):
def action(
function=None, *, permissions=None, description=None, label=None, attrs=None
):
"""
Conveniently add attributes to an action function::
Expand Down Expand Up @@ -346,6 +348,8 @@ def decorator(func):
func.short_description = description
if label is not None:
func.label = label
if attrs is not None:
func.attrs = attrs
return func

if function is None:
Expand Down
32 changes: 17 additions & 15 deletions example_project/polls/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
from django.http import HttpResponseRedirect
from django.urls import reverse

from django_object_actions import DjangoObjectActions, takes_instance_or_queryset
from django_object_actions import (
DjangoObjectActions,
takes_instance_or_queryset,
action,
)

from .models import Choice, Poll, Comment, RelatedData

Expand All @@ -15,38 +19,37 @@ class ChoiceAdmin(DjangoObjectActions, admin.ModelAdmin):
# Actions
#########

@action(
description="+1",
label="vote++",
attrs={
"test": '"foo&bar"',
"Robert": '"); DROP TABLE Students; ', # 327
"class": "addlink",
},
)
@takes_instance_or_queryset
def increment_vote(self, request, queryset):
queryset.update(votes=F("votes") + 1)

increment_vote.short_description = "+1"
increment_vote.label = "vote++"
increment_vote.attrs = {
"test": '"foo&bar"',
"Robert": '"); DROP TABLE Students; ', # 327
"class": "addlink",
}

actions = ["increment_vote"]

# Object actions
################

@action(description="-1")
def decrement_vote(self, request, obj):
obj.votes -= 1
obj.save()

decrement_vote.short_description = "-1"

def delete_all(self, request, queryset):
self.message_user(request, "just kidding!")

@action(description="0")
def reset_vote(self, request, obj):
obj.votes = 0
obj.save()

reset_vote.short_description = "0"

def edit_poll(self, request, obj):
url = reverse("admin:polls_poll_change", args=(obj.poll.pk,))
return HttpResponseRedirect(url)
Expand Down Expand Up @@ -101,6 +104,7 @@ def change_view(self, request, object_id, form_url="", extra_context=None):
# Object actions
################

@action(label="Delete All Choices")
def delete_all_choices(self, request, obj):
from django.shortcuts import render

Expand All @@ -111,8 +115,6 @@ def delete_all_choices(self, request, obj):
self.message_user(request, "All choices deleted")
return render(request, "clear_choices.html", {"object": obj})

delete_all_choices.label = "Delete All Choices"

def question_mark(self, request, obj):
"""Add a question mark."""
obj.question = obj.question + "?"
Expand Down

0 comments on commit 425b4b6

Please sign in to comment.