diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 5c16dcfad1..1703dd333e 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -857,6 +857,10 @@ class ModelAdmin(BaseModelAdmin): return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, str(obj.pk)) action_checkbox.short_description = mark_safe('') + @staticmethod + def _get_action_description(func, name): + return getattr(func, 'short_description', capfirst(name.replace('_', ' '))) + def _get_base_actions(self): """Return the list of actions, prior to any request-based filtering.""" actions = [] @@ -869,7 +873,7 @@ class ModelAdmin(BaseModelAdmin): for (name, func) in self.admin_site.actions: if name in base_action_names: continue - description = getattr(func, 'short_description', name.replace('_', ' ')) + description = self._get_action_description(func, name) actions.append((func, name, description)) # Add actions from this ModelAdmin. actions.extend(base_actions) @@ -938,10 +942,7 @@ class ModelAdmin(BaseModelAdmin): except KeyError: return None - if hasattr(func, 'short_description'): - description = func.short_description - else: - description = capfirst(action.replace('_', ' ')) + description = self._get_action_description(func, action) return func, action, description def get_list_display(self, request): diff --git a/tests/modeladmin/test_actions.py b/tests/modeladmin/test_actions.py index 76f2f96c03..f7de725ffc 100644 --- a/tests/modeladmin/test_actions.py +++ b/tests/modeladmin/test_actions.py @@ -77,6 +77,31 @@ class AdminActionsTests(TestCase): action_names = [name for _, name, _ in ma2._get_base_actions()] self.assertEqual(action_names, ['delete_selected']) + def test_global_actions_description(self): + def global_action_1(modeladmin, request, queryset): + pass + + def global_action_2(modeladmin, request, queryset): + pass + + global_action_1.short_description = 'Site-wide admin action 1.' + admin_site = admin.AdminSite() + admin_site.add_action(global_action_1) + admin_site.add_action(global_action_2) + + class BandAdmin(admin.ModelAdmin): + pass + + ma = BandAdmin(Band, admin_site) + self.assertEqual( + [description for _, _, description in ma._get_base_actions()], + [ + 'Delete selected %(verbose_name_plural)s', + 'Site-wide admin action 1.', + 'Global action 2', + ], + ) + def test_actions_replace_global_action(self): def global_action_1(modeladmin, request, queryset): pass