Skip to content

Commit c61d809

Browse files
committed
Add label/description decorator
Reference: crccheck#115
1 parent 700dd9b commit c61d809

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

django_object_actions/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
BaseDjangoObjectActions,
88
DjangoObjectActions,
99
takes_instance_or_queryset,
10+
action,
1011
)

django_object_actions/tests/test_utils.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
from django.test import TestCase
44
from example_project.polls.models import Poll
55

6-
from ..utils import BaseDjangoObjectActions, BaseActionView, takes_instance_or_queryset
6+
from ..utils import (
7+
BaseDjangoObjectActions,
8+
BaseActionView,
9+
takes_instance_or_queryset,
10+
action,
11+
)
712

813

914
class BaseDjangoObjectActionsTest(TestCase):
@@ -122,3 +127,23 @@ def myfunc(foo, bar, queryset):
122127
queryset = myfunc(None, None, queryset=self.obj)
123128
# the resulting queryset only has one item and it's self.obj
124129
self.assertEqual(queryset.get(), self.obj)
130+
131+
132+
class DecoratorActionTest(TestCase):
133+
def test_decorated(self):
134+
# setup
135+
@action(description="First action of this admin site.")
136+
def action_1(modeladmin, request, queryset):
137+
pass
138+
139+
@action(permissions=["do_action2"])
140+
def action_2(modeladmin, request, queryset):
141+
pass
142+
143+
@action(label="Third action")
144+
def action_3(modeladmin, request, queryset):
145+
pass
146+
147+
self.assertEqual(action_1.short_description, "First action of this admin site.")
148+
self.assertEqual(action_2.allowed_permissions, ["do_action2"])
149+
self.assertEqual(action_3.label, "Third action")

django_object_actions/utils.py

+41
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,44 @@ def decorated_function(self, request, queryset):
311311
return func(self, request, queryset)
312312

313313
return decorated_function
314+
315+
316+
def action(function=None, *, permissions=None, description=None, label=None):
317+
"""
318+
Conveniently add attributes to an action function::
319+
320+
@admin_action(
321+
permissions=['publish'],
322+
description='Mark selected stories as published',
323+
label='Publish'
324+
)
325+
def make_published(self, request, queryset):
326+
queryset.update(status='p')
327+
328+
This is equivalent to setting some attributes (with the original, longer
329+
names) on the function directly::
330+
331+
def make_published(self, request, queryset):
332+
queryset.update(status='p')
333+
make_published.allowed_permissions = ['publish']
334+
make_published.short_description = 'Mark selected stories as published'
335+
make_published.label = 'Publish'
336+
337+
This is the django-object-actions equivalent of
338+
https://docs.djangoproject.com
339+
/en/dev/ref/contrib/admin/actions/#django.contrib.admin.action
340+
"""
341+
342+
def decorator(func):
343+
if permissions is not None:
344+
func.allowed_permissions = permissions
345+
if description is not None:
346+
func.short_description = description
347+
if label is not None:
348+
func.label = label
349+
return func
350+
351+
if function is None:
352+
return decorator
353+
else:
354+
return decorator(function)

0 commit comments

Comments
 (0)