Skip to content

Commit 601a77a

Browse files
Closes #19735: Implement reuable bulk operations classes (#19774)
* Initial work on #19735 * Work in progress * Remove ClusterRemoveDevicesView (anti-pattern) * Misc cleanup * Fix has_bulk_actions * Fix has_bulk_actions for ObjectChildrenView * Restore clone button * Misc cleanup * Clean up custom bulk actions * Rename individual object actions * Collapse into a single template tag * Fix support for legacy action dicts * Rename bulk attr to multi * clone_button tag should fail silently if view name is invalid * Clean up action buttons * Fix export button label * Replace clone_button with an ObjectAction * Create object actions for adding device/VM components * Move core_sync.html to core app * Remove extra_bulk_buttons from template doc
1 parent 71e6ea5 commit 601a77a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+567
-973
lines changed

netbox/core/object_actions.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from django.utils.translation import gettext as _
2+
3+
from netbox.object_actions import ObjectAction
4+
5+
__all__ = (
6+
'BulkSync',
7+
)
8+
9+
10+
class BulkSync(ObjectAction):
11+
"""
12+
Synchronize multiple objects at once.
13+
"""
14+
name = 'bulk_sync'
15+
label = _('Sync Data')
16+
multi = True
17+
permissions_required = {'sync'}
18+
template_name = 'core/buttons/bulk_sync.html'

netbox/core/views.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from core.utils import delete_rq_job, enqueue_rq_job, get_rq_jobs_from_status, requeue_rq_job, stop_rq_job
2424
from netbox.config import get_config, PARAMS
25+
from netbox.object_actions import AddObject, BulkDelete, BulkExport, DeleteObject
2526
from netbox.registry import registry
2627
from netbox.views import generic
2728
from netbox.views.generic.base import BaseObjectView
@@ -138,14 +139,13 @@ class DataFileListView(generic.ObjectListView):
138139
filterset = filtersets.DataFileFilterSet
139140
filterset_form = forms.DataFileFilterForm
140141
table = tables.DataFileTable
141-
actions = {
142-
'bulk_delete': {'delete'},
143-
}
142+
actions = (BulkDelete,)
144143

145144

146145
@register_model_view(DataFile)
147146
class DataFileView(generic.ObjectView):
148147
queryset = DataFile.objects.all()
148+
actions = (DeleteObject,)
149149

150150

151151
@register_model_view(DataFile, 'delete')
@@ -170,15 +170,13 @@ class JobListView(generic.ObjectListView):
170170
filterset = filtersets.JobFilterSet
171171
filterset_form = forms.JobFilterForm
172172
table = tables.JobTable
173-
actions = {
174-
'export': {'view'},
175-
'bulk_delete': {'delete'},
176-
}
173+
actions = (BulkExport, BulkDelete)
177174

178175

179176
@register_model_view(Job)
180177
class JobView(generic.ObjectView):
181178
queryset = Job.objects.all()
179+
actions = (DeleteObject,)
182180

183181

184182
@register_model_view(Job, 'delete')
@@ -204,9 +202,7 @@ class ObjectChangeListView(generic.ObjectListView):
204202
filterset_form = forms.ObjectChangeFilterForm
205203
table = tables.ObjectChangeTable
206204
template_name = 'core/objectchange_list.html'
207-
actions = {
208-
'export': {'view'},
209-
}
205+
actions = (BulkExport,)
210206

211207

212208
@register_model_view(ObjectChange)
@@ -274,6 +270,7 @@ class ConfigRevisionListView(generic.ObjectListView):
274270
filterset = filtersets.ConfigRevisionFilterSet
275271
filterset_form = forms.ConfigRevisionFilterForm
276272
table = tables.ConfigRevisionTable
273+
actions = (AddObject, BulkExport)
277274

278275

279276
@register_model_view(ConfigRevision)

netbox/dcim/object_actions.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from django.utils.translation import gettext as _
2+
3+
from netbox.object_actions import ObjectAction
4+
5+
__all__ = (
6+
'BulkAddComponents',
7+
'BulkDisconnect',
8+
)
9+
10+
11+
class BulkAddComponents(ObjectAction):
12+
"""
13+
Add components to the selected devices.
14+
"""
15+
label = _('Add Components')
16+
multi = True
17+
permissions_required = {'change'}
18+
template_name = 'dcim/buttons/bulk_add_components.html'
19+
20+
@classmethod
21+
def get_context(cls, context, obj):
22+
return {
23+
'perms': context.get('perms'),
24+
'request': context.get('request'),
25+
'formaction': context.get('formaction'),
26+
'label': cls.label,
27+
}
28+
29+
30+
class BulkDisconnect(ObjectAction):
31+
"""
32+
Disconnect each of a set of objects to which a cable is connected.
33+
"""
34+
name = 'bulk_disconnect'
35+
label = _('Disconnect Selected')
36+
multi = True
37+
permissions_required = {'change'}
38+
template_name = 'dcim/buttons/bulk_disconnect.html'

0 commit comments

Comments
 (0)