diff --git a/netbox/netbox/object_actions.py b/netbox/netbox/object_actions.py
index fcf63d088..1a72e124f 100644
--- a/netbox/netbox/object_actions.py
+++ b/netbox/netbox/object_actions.py
@@ -91,7 +91,8 @@ class BulkExport(ObjectAction):
permissions_required = {'view'}
template_name = 'buttons/export.html'
- def get_context(self, context, model):
+ @classmethod
+ def get_context(cls, context, model):
object_type = ObjectType.objects.get_for_model(model)
user = context['request'].user
diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py
index a4ea1ac64..477a36e90 100644
--- a/netbox/netbox/views/generic/bulk_views.py
+++ b/netbox/netbox/views/generic/bulk_views.py
@@ -152,7 +152,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
# Determine the available actions
actions = self.get_permitted_actions(request.user)
- has_bulk_actions = any(action.bulk for action in actions.values())
+ has_bulk_actions = any(action.bulk for action in actions)
if 'export' in request.GET:
diff --git a/netbox/netbox/views/generic/mixins.py b/netbox/netbox/views/generic/mixins.py
index 8732fefb4..5502e2447 100644
--- a/netbox/netbox/views/generic/mixins.py
+++ b/netbox/netbox/views/generic/mixins.py
@@ -59,9 +59,7 @@ class ActionsMixin:
if not required_permissions or user.has_perms(required_permissions):
permitted_actions.append(action)
- return {
- action.name: action for action in permitted_actions
- }
+ return permitted_actions
class TableMixin:
diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py
index ca64f46a6..989e1f7a9 100644
--- a/netbox/netbox/views/generic/object_views.py
+++ b/netbox/netbox/views/generic/object_views.py
@@ -143,7 +143,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
# Determine the available actions
actions = self.get_permitted_actions(request.user, model=self.child_model)
- has_bulk_actions = any(action.bulk for action in actions.values())
+ has_bulk_actions = any(action.bulk for action in actions)
table_data = self.prep_table_data(request, child_objects, instance)
table = self.get_table(table_data, request, has_bulk_actions)
diff --git a/netbox/templates/generic/object.html b/netbox/templates/generic/object.html
index 4851dc3e6..64086855e 100644
--- a/netbox/templates/generic/object.html
+++ b/netbox/templates/generic/object.html
@@ -83,9 +83,7 @@ Context:
{% if request.user|can_add:object %}
{% clone_button object %}
{% endif %}
- {% for name, action in actions.items %}
- {% action_button action object %}
- {% endfor %}
+ {% action_buttons actions object %}
{% endblock control-buttons %}
diff --git a/netbox/templates/generic/object_children.html b/netbox/templates/generic/object_children.html
index fe68d4231..ff422a06f 100644
--- a/netbox/templates/generic/object_children.html
+++ b/netbox/templates/generic/object_children.html
@@ -37,9 +37,7 @@ Context:
{% block bulk_controls %}
- {% for name, action in actions.items %}
- {% bulk_action_button action model %}
- {% endfor %}
+ {% action_buttons actions model bulk=True %}
{% block bulk_extra_controls %}{% endblock %}
{% endblock bulk_controls %}
diff --git a/netbox/templates/generic/object_list.html b/netbox/templates/generic/object_list.html
index c412ae8ac..a9aa0f678 100644
--- a/netbox/templates/generic/object_list.html
+++ b/netbox/templates/generic/object_list.html
@@ -32,11 +32,7 @@ Context:
{% plugin_list_buttons model %}
{% block extra_controls %}{% endblock %}
- {% for name, action in actions.items %}
- {% if not action.bulk %}
- {% action_button action model %}
- {% endif %}
- {% endfor %}
+ {% action_buttons actions model %}
{% endblock controls %}
@@ -88,9 +84,7 @@ Context:
- {% for name, action in actions.items %}
- {% bulk_action_button action model %}
- {% endfor %}
+ {% action_buttons actions model bulk=True %}
@@ -118,13 +112,8 @@ Context:
{% block bulk_buttons %}
- {# Extra bulk buttons #}
{% block extra_bulk_buttons %}{% endblock %}
-
- {# Default bulk action buttons #}
- {% for name, action in actions.items %}
- {% bulk_action_button action model %}
- {% endfor %}
+ {% action_buttons actions model bulk=True %}
{% endblock %}
diff --git a/netbox/utilities/templatetags/buttons.py b/netbox/utilities/templatetags/buttons.py
index 37e1e514f..3a19ccf62 100644
--- a/netbox/utilities/templatetags/buttons.py
+++ b/netbox/utilities/templatetags/buttons.py
@@ -2,6 +2,7 @@ from django import template
from django.contrib.contenttypes.models import ContentType
from django.template import loader
from django.urls import NoReverseMatch, reverse
+from django.utils.safestring import mark_safe
from core.models import ObjectType
from extras.models import Bookmark, ExportTemplate, Subscription
@@ -10,10 +11,9 @@ from utilities.querydict import prepare_cloned_fields
from utilities.views import get_viewname
__all__ = (
- 'action_button',
+ 'action_buttons',
'add_button',
'bookmark_button',
- 'bulk_action_button',
'bulk_delete_button',
'bulk_edit_button',
'clone_button',
@@ -28,8 +28,17 @@ __all__ = (
register = template.Library()
+@register.simple_tag(takes_context=True)
+def action_buttons(context, actions, obj, bulk=False):
+ buttons = [
+ loader.render_to_string(action.template_name, action.get_context(context, obj))
+ for action in actions if action.bulk == bulk
+ ]
+ return mark_safe(''.join(buttons))
+
+
#
-# Instance buttons
+# Legacy object buttons
#
@register.inclusion_tag('buttons/bookmark.html', takes_context=True)
@@ -145,7 +154,7 @@ def sync_button(instance):
#
-# List buttons
+# Legacy list buttons
#
@register.inclusion_tag('buttons/add.html')
@@ -220,17 +229,3 @@ def bulk_delete_button(context, model, action='bulk_delete', query_params=None):
'htmx_navigation': context.get('htmx_navigation'),
'url': url,
}
-
-
-@register.simple_tag(takes_context=True)
-def action_button(context, action, obj):
- if action.bulk:
- return ''
- return loader.render_to_string(action.template_name, action.get_context(context, obj))
-
-
-@register.simple_tag(takes_context=True)
-def bulk_action_button(context, action, model):
- if not action.bulk:
- return ''
- return loader.render_to_string(action.template_name, action.get_context(context, model))