Closes #19231: Add bulk renaming support for all models (#19795)

* Closes #19231: Add bulk renaming support for all models

* Introduce a template filter for getattr()

* Extend BulkRenameView to support arbitrary field names

* Address bulk renaming support for remaining models

* Bulk rename URL resolution should fail silently

* Update documentation

* Fix bulk button rendering for HTMX requests
This commit is contained in:
Jeremy Stretch 2025-07-02 14:35:34 -04:00 committed by GitHub
parent 601a77ac73
commit ce12de8b6d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 465 additions and 46 deletions

View File

@ -64,6 +64,7 @@ Generic view classes (documented below) facilitate common operations, such as cr
| `ObjectListView` | View a list of objects | | `ObjectListView` | View a list of objects |
| `BulkImportView` | Import a set of new objects | | `BulkImportView` | Import a set of new objects |
| `BulkEditView` | Edit multiple objects | | `BulkEditView` | Edit multiple objects |
| `BulkRenameView` | Rename multiple objects |
| `BulkDeleteView` | Delete multiple objects | | `BulkDeleteView` | Delete multiple objects |
!!! warning !!! warning
@ -171,6 +172,10 @@ Below are the class definitions for NetBox's multi-object views. These views han
options: options:
members: false members: false
::: netbox.views.generic.BulkRenameView
options:
members: false
::: netbox.views.generic.BulkDeleteView ::: netbox.views.generic.BulkDeleteView
options: options:
members: members:

View File

@ -5,6 +5,7 @@ from django.utils.translation import gettext_lazy as _
from dcim.views import PathTraceView from dcim.views import PathTraceView
from ipam.models import ASN from ipam.models import ASN
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport
from netbox.views import generic from netbox.views import generic
from utilities.forms import ConfirmationForm from utilities.forms import ConfirmationForm
from utilities.query import count_related from utilities.query import count_related
@ -79,6 +80,11 @@ class ProviderBulkEditView(generic.BulkEditView):
form = forms.ProviderBulkEditForm form = forms.ProviderBulkEditForm
@register_model_view(Provider, 'bulk_rename', path='rename', detail=False)
class ProviderBulkRenameView(generic.BulkRenameView):
queryset = Provider.objects.all()
@register_model_view(Provider, 'bulk_delete', path='delete', detail=False) @register_model_view(Provider, 'bulk_delete', path='delete', detail=False)
class ProviderBulkDeleteView(generic.BulkDeleteView): class ProviderBulkDeleteView(generic.BulkDeleteView):
queryset = Provider.objects.annotate( queryset = Provider.objects.annotate(
@ -141,6 +147,11 @@ class ProviderAccountBulkEditView(generic.BulkEditView):
form = forms.ProviderAccountBulkEditForm form = forms.ProviderAccountBulkEditForm
@register_model_view(ProviderAccount, 'bulk_rename', path='rename', detail=False)
class ProviderAccountBulkRenameView(generic.BulkRenameView):
queryset = ProviderAccount.objects.all()
@register_model_view(ProviderAccount, 'bulk_delete', path='delete', detail=False) @register_model_view(ProviderAccount, 'bulk_delete', path='delete', detail=False)
class ProviderAccountBulkDeleteView(generic.BulkDeleteView): class ProviderAccountBulkDeleteView(generic.BulkDeleteView):
queryset = ProviderAccount.objects.annotate( queryset = ProviderAccount.objects.annotate(
@ -212,6 +223,11 @@ class ProviderNetworkBulkEditView(generic.BulkEditView):
form = forms.ProviderNetworkBulkEditForm form = forms.ProviderNetworkBulkEditForm
@register_model_view(ProviderNetwork, 'bulk_rename', path='rename', detail=False)
class ProviderNetworkBulkRenameView(generic.BulkRenameView):
queryset = ProviderNetwork.objects.all()
@register_model_view(ProviderNetwork, 'bulk_delete', path='delete', detail=False) @register_model_view(ProviderNetwork, 'bulk_delete', path='delete', detail=False)
class ProviderNetworkBulkDeleteView(generic.BulkDeleteView): class ProviderNetworkBulkDeleteView(generic.BulkDeleteView):
queryset = ProviderNetwork.objects.all() queryset = ProviderNetwork.objects.all()
@ -271,6 +287,11 @@ class CircuitTypeBulkEditView(generic.BulkEditView):
form = forms.CircuitTypeBulkEditForm form = forms.CircuitTypeBulkEditForm
@register_model_view(CircuitType, 'bulk_rename', path='rename', detail=False)
class CircuitTypeBulkRenameView(generic.BulkRenameView):
queryset = CircuitType.objects.all()
@register_model_view(CircuitType, 'bulk_delete', path='delete', detail=False) @register_model_view(CircuitType, 'bulk_delete', path='delete', detail=False)
class CircuitTypeBulkDeleteView(generic.BulkDeleteView): class CircuitTypeBulkDeleteView(generic.BulkDeleteView):
queryset = CircuitType.objects.annotate( queryset = CircuitType.objects.annotate(
@ -337,6 +358,12 @@ class CircuitBulkEditView(generic.BulkEditView):
form = forms.CircuitBulkEditForm form = forms.CircuitBulkEditForm
@register_model_view(Circuit, 'bulk_rename', path='rename', detail=False)
class CircuitBulkRenameView(generic.BulkRenameView):
queryset = Circuit.objects.all()
field_name = 'cid'
@register_model_view(Circuit, 'bulk_delete', path='delete', detail=False) @register_model_view(Circuit, 'bulk_delete', path='delete', detail=False)
class CircuitBulkDeleteView(generic.BulkDeleteView): class CircuitBulkDeleteView(generic.BulkDeleteView):
queryset = Circuit.objects.prefetch_related( queryset = Circuit.objects.prefetch_related(
@ -432,6 +459,7 @@ class CircuitTerminationListView(generic.ObjectListView):
filterset = filtersets.CircuitTerminationFilterSet filterset = filtersets.CircuitTerminationFilterSet
filterset_form = forms.CircuitTerminationFilterForm filterset_form = forms.CircuitTerminationFilterForm
table = tables.CircuitTerminationTable table = tables.CircuitTerminationTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(CircuitTermination) @register_model_view(CircuitTermination)
@ -526,6 +554,11 @@ class CircuitGroupBulkEditView(generic.BulkEditView):
form = forms.CircuitGroupBulkEditForm form = forms.CircuitGroupBulkEditForm
@register_model_view(CircuitGroup, 'bulk_rename', path='rename', detail=False)
class CircuitGroupBulkRenameView(generic.BulkRenameView):
queryset = CircuitGroup.objects.all()
@register_model_view(CircuitGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(CircuitGroup, 'bulk_delete', path='delete', detail=False)
class CircuitGroupBulkDeleteView(generic.BulkDeleteView): class CircuitGroupBulkDeleteView(generic.BulkDeleteView):
queryset = CircuitGroup.objects.all() queryset = CircuitGroup.objects.all()
@ -543,6 +576,7 @@ class CircuitGroupAssignmentListView(generic.ObjectListView):
filterset = filtersets.CircuitGroupAssignmentFilterSet filterset = filtersets.CircuitGroupAssignmentFilterSet
filterset_form = forms.CircuitGroupAssignmentFilterForm filterset_form = forms.CircuitGroupAssignmentFilterForm
table = tables.CircuitGroupAssignmentTable table = tables.CircuitGroupAssignmentTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(CircuitGroupAssignment) @register_model_view(CircuitGroupAssignment)
@ -635,6 +669,11 @@ class VirtualCircuitTypeBulkEditView(generic.BulkEditView):
form = forms.VirtualCircuitTypeBulkEditForm form = forms.VirtualCircuitTypeBulkEditForm
@register_model_view(VirtualCircuitType, 'bulk_rename', path='rename', detail=False)
class VirtualCircuitTypeBulkRenameView(generic.BulkRenameView):
queryset = VirtualCircuitType.objects.all()
@register_model_view(VirtualCircuitType, 'bulk_delete', path='delete', detail=False) @register_model_view(VirtualCircuitType, 'bulk_delete', path='delete', detail=False)
class VirtualCircuitTypeBulkDeleteView(generic.BulkDeleteView): class VirtualCircuitTypeBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualCircuitType.objects.annotate( queryset = VirtualCircuitType.objects.annotate(
@ -697,6 +736,12 @@ class VirtualCircuitBulkEditView(generic.BulkEditView):
form = forms.VirtualCircuitBulkEditForm form = forms.VirtualCircuitBulkEditForm
@register_model_view(VirtualCircuit, 'bulk_rename', path='rename', detail=False)
class VirtualCircuitulkRenameView(generic.BulkRenameView):
queryset = VirtualCircuit.objects.all()
field_name = 'cid'
class VirtualCircuitBulkDeleteView(generic.BulkDeleteView): class VirtualCircuitBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualCircuit.objects.annotate( queryset = VirtualCircuit.objects.annotate(
termination_count=count_related(VirtualCircuitTermination, 'virtual_circuit') termination_count=count_related(VirtualCircuitTermination, 'virtual_circuit')
@ -714,6 +759,7 @@ class VirtualCircuitTerminationListView(generic.ObjectListView):
filterset = filtersets.VirtualCircuitTerminationFilterSet filterset = filtersets.VirtualCircuitTerminationFilterSet
filterset_form = forms.VirtualCircuitTerminationFilterForm filterset_form = forms.VirtualCircuitTerminationFilterForm
table = tables.VirtualCircuitTerminationTable table = tables.VirtualCircuitTerminationTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(VirtualCircuitTermination) @register_model_view(VirtualCircuitTermination)

View File

@ -120,6 +120,11 @@ class DataSourceBulkEditView(generic.BulkEditView):
form = forms.DataSourceBulkEditForm form = forms.DataSourceBulkEditForm
@register_model_view(DataSource, 'bulk_rename', path='rename', detail=False)
class DataSourceBulkRenameView(generic.BulkRenameView):
queryset = DataSource.objects.all()
@register_model_view(DataSource, 'bulk_delete', path='delete', detail=False) @register_model_view(DataSource, 'bulk_delete', path='delete', detail=False)
class DataSourceBulkDeleteView(generic.BulkDeleteView): class DataSourceBulkDeleteView(generic.BulkDeleteView):
queryset = DataSource.objects.annotate( queryset = DataSource.objects.annotate(

View File

@ -292,6 +292,11 @@ class RegionBulkEditView(generic.BulkEditView):
form = forms.RegionBulkEditForm form = forms.RegionBulkEditForm
@register_model_view(Region, 'bulk_rename', path='rename', detail=False)
class RegionBulkRenameView(generic.BulkRenameView):
queryset = Region.objects.all()
@register_model_view(Region, 'bulk_delete', path='delete', detail=False) @register_model_view(Region, 'bulk_delete', path='delete', detail=False)
class RegionBulkDeleteView(generic.BulkDeleteView): class RegionBulkDeleteView(generic.BulkDeleteView):
queryset = Region.objects.add_related_count( queryset = Region.objects.add_related_count(
@ -418,6 +423,11 @@ class SiteGroupBulkEditView(generic.BulkEditView):
form = forms.SiteGroupBulkEditForm form = forms.SiteGroupBulkEditForm
@register_model_view(SiteGroup, 'bulk_rename', path='rename', detail=False)
class SiteGroupBulkRenameView(generic.BulkRenameView):
queryset = SiteGroup.objects.all()
@register_model_view(SiteGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(SiteGroup, 'bulk_delete', path='delete', detail=False)
class SiteGroupBulkDeleteView(generic.BulkDeleteView): class SiteGroupBulkDeleteView(generic.BulkDeleteView):
queryset = SiteGroup.objects.add_related_count( queryset = SiteGroup.objects.add_related_count(
@ -503,6 +513,11 @@ class SiteBulkEditView(generic.BulkEditView):
form = forms.SiteBulkEditForm form = forms.SiteBulkEditForm
@register_model_view(Site, 'bulk_rename', path='rename', detail=False)
class SiteBulkRenameView(generic.BulkRenameView):
queryset = Site.objects.all()
@register_model_view(Site, 'bulk_delete', path='delete', detail=False) @register_model_view(Site, 'bulk_delete', path='delete', detail=False)
class SiteBulkDeleteView(generic.BulkDeleteView): class SiteBulkDeleteView(generic.BulkDeleteView):
queryset = Site.objects.all() queryset = Site.objects.all()
@ -607,6 +622,11 @@ class LocationBulkEditView(generic.BulkEditView):
form = forms.LocationBulkEditForm form = forms.LocationBulkEditForm
@register_model_view(Location, 'bulk_rename', path='rename', detail=False)
class LocationBulkRenameView(generic.BulkRenameView):
queryset = Location.objects.all()
@register_model_view(Location, 'bulk_delete', path='delete', detail=False) @register_model_view(Location, 'bulk_delete', path='delete', detail=False)
class LocationBulkDeleteView(generic.BulkDeleteView): class LocationBulkDeleteView(generic.BulkDeleteView):
queryset = Location.objects.add_related_count( queryset = Location.objects.add_related_count(
@ -672,6 +692,11 @@ class RackRoleBulkEditView(generic.BulkEditView):
form = forms.RackRoleBulkEditForm form = forms.RackRoleBulkEditForm
@register_model_view(RackRole, 'bulk_rename', path='rename', detail=False)
class RackRoleBulkRenameView(generic.BulkRenameView):
queryset = RackRole.objects.all()
@register_model_view(RackRole, 'bulk_delete', path='delete', detail=False) @register_model_view(RackRole, 'bulk_delete', path='delete', detail=False)
class RackRoleBulkDeleteView(generic.BulkDeleteView): class RackRoleBulkDeleteView(generic.BulkDeleteView):
queryset = RackRole.objects.annotate( queryset = RackRole.objects.annotate(
@ -731,6 +756,12 @@ class RackTypeBulkEditView(generic.BulkEditView):
form = forms.RackTypeBulkEditForm form = forms.RackTypeBulkEditForm
@register_model_view(RackType, 'bulk_rename', path='rename', detail=False)
class RackTypeBulkRenameView(generic.BulkRenameView):
queryset = RackType.objects.all()
field_name = 'model'
@register_model_view(RackType, 'bulk_delete', path='delete', detail=False) @register_model_view(RackType, 'bulk_delete', path='delete', detail=False)
class RackTypeBulkDeleteView(generic.BulkDeleteView): class RackTypeBulkDeleteView(generic.BulkDeleteView):
queryset = RackType.objects.all() queryset = RackType.objects.all()
@ -910,6 +941,11 @@ class RackBulkEditView(generic.BulkEditView):
form = forms.RackBulkEditForm form = forms.RackBulkEditForm
@register_model_view(Rack, 'bulk_rename', path='rename', detail=False)
class RackBulkRenameView(generic.BulkRenameView):
queryset = Rack.objects.all()
@register_model_view(Rack, 'bulk_delete', path='delete', detail=False) @register_model_view(Rack, 'bulk_delete', path='delete', detail=False)
class RackBulkDeleteView(generic.BulkDeleteView): class RackBulkDeleteView(generic.BulkDeleteView):
queryset = Rack.objects.all() queryset = Rack.objects.all()
@ -927,6 +963,7 @@ class RackReservationListView(generic.ObjectListView):
filterset = filtersets.RackReservationFilterSet filterset = filtersets.RackReservationFilterSet
filterset_form = forms.RackReservationFilterForm filterset_form = forms.RackReservationFilterForm
table = tables.RackReservationTable table = tables.RackReservationTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(RackReservation) @register_model_view(RackReservation)
@ -1043,6 +1080,11 @@ class ManufacturerBulkEditView(generic.BulkEditView):
form = forms.ManufacturerBulkEditForm form = forms.ManufacturerBulkEditForm
@register_model_view(Manufacturer, 'bulk_rename', path='rename', detail=False)
class ManufacturerBulkRenameView(generic.BulkRenameView):
queryset = Manufacturer.objects.all()
@register_model_view(Manufacturer, 'bulk_delete', path='delete', detail=False) @register_model_view(Manufacturer, 'bulk_delete', path='delete', detail=False)
class ManufacturerBulkDeleteView(generic.BulkDeleteView): class ManufacturerBulkDeleteView(generic.BulkDeleteView):
queryset = Manufacturer.objects.annotate( queryset = Manufacturer.objects.annotate(
@ -1290,6 +1332,12 @@ class DeviceTypeBulkEditView(generic.BulkEditView):
form = forms.DeviceTypeBulkEditForm form = forms.DeviceTypeBulkEditForm
@register_model_view(DeviceType, 'bulk_rename', path='rename', detail=False)
class DeviceTypeBulkRenameView(generic.BulkRenameView):
queryset = DeviceType.objects.all()
field_name = 'model'
@register_model_view(DeviceType, 'bulk_delete', path='delete', detail=False) @register_model_view(DeviceType, 'bulk_delete', path='delete', detail=False)
class DeviceTypeBulkDeleteView(generic.BulkDeleteView): class DeviceTypeBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceType.objects.annotate( queryset = DeviceType.objects.annotate(
@ -1346,6 +1394,11 @@ class ModuleTypeProfileBulkEditView(generic.BulkEditView):
form = forms.ModuleTypeProfileBulkEditForm form = forms.ModuleTypeProfileBulkEditForm
@register_model_view(ModuleTypeProfile, 'bulk_rename', path='rename', detail=False)
class ModuleTypeProfileBulkRenameView(generic.BulkRenameView):
queryset = ModuleTypeProfile.objects.all()
@register_model_view(ModuleTypeProfile, 'bulk_delete', path='delete', detail=False) @register_model_view(ModuleTypeProfile, 'bulk_delete', path='delete', detail=False)
class ModuleTypeProfileBulkDeleteView(generic.BulkDeleteView): class ModuleTypeProfileBulkDeleteView(generic.BulkDeleteView):
queryset = ModuleTypeProfile.objects.annotate( queryset = ModuleTypeProfile.objects.annotate(
@ -1556,6 +1609,11 @@ class ModuleTypeBulkEditView(generic.BulkEditView):
form = forms.ModuleTypeBulkEditForm form = forms.ModuleTypeBulkEditForm
@register_model_view(ModuleType, 'bulk_rename', path='rename', detail=False)
class ModuleTypeBulkRenameView(generic.BulkRenameView):
queryset = ModuleType.objects.all()
@register_model_view(ModuleType, 'bulk_delete', path='delete', detail=False) @register_model_view(ModuleType, 'bulk_delete', path='delete', detail=False)
class ModuleTypeBulkDeleteView(generic.BulkDeleteView): class ModuleTypeBulkDeleteView(generic.BulkDeleteView):
queryset = ModuleType.objects.annotate( queryset = ModuleType.objects.annotate(
@ -2030,6 +2088,11 @@ class DeviceRoleBulkEditView(generic.BulkEditView):
form = forms.DeviceRoleBulkEditForm form = forms.DeviceRoleBulkEditForm
@register_model_view(DeviceRole, 'bulk_rename', path='rename', detail=False)
class DeviceRoleBulkRenameView(generic.BulkRenameView):
queryset = DeviceRole.objects.all()
@register_model_view(DeviceRole, 'bulk_delete', path='delete', detail=False) @register_model_view(DeviceRole, 'bulk_delete', path='delete', detail=False)
class DeviceRoleBulkDeleteView(generic.BulkDeleteView): class DeviceRoleBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceRole.objects.annotate( queryset = DeviceRole.objects.annotate(
@ -2091,6 +2154,11 @@ class PlatformBulkEditView(generic.BulkEditView):
form = forms.PlatformBulkEditForm form = forms.PlatformBulkEditForm
@register_model_view(Platform, 'bulk_rename', path='rename', detail=False)
class PlatformBulkRenameView(generic.BulkRenameView):
queryset = Platform.objects.all()
@register_model_view(Platform, 'bulk_delete', path='delete', detail=False) @register_model_view(Platform, 'bulk_delete', path='delete', detail=False)
class PlatformBulkDeleteView(generic.BulkDeleteView): class PlatformBulkDeleteView(generic.BulkDeleteView):
queryset = Platform.objects.all() queryset = Platform.objects.all()
@ -2374,16 +2442,16 @@ class DeviceBulkEditView(generic.BulkEditView):
form = forms.DeviceBulkEditForm form = forms.DeviceBulkEditForm
@register_model_view(Device, 'bulk_delete', path='delete', detail=False) @register_model_view(Device, 'bulk_rename', path='rename', detail=False)
class DeviceBulkDeleteView(generic.BulkDeleteView): class DeviceBulkRenameView(generic.BulkRenameView):
queryset = Device.objects.prefetch_related('device_type__manufacturer') queryset = Device.objects.all()
filterset = filtersets.DeviceFilterSet filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable table = tables.DeviceTable
@register_model_view(Device, 'bulk_rename', path='rename', detail=False) @register_model_view(Device, 'bulk_delete', path='delete', detail=False)
class DeviceBulkRenameView(generic.BulkRenameView): class DeviceBulkDeleteView(generic.BulkDeleteView):
queryset = Device.objects.all() queryset = Device.objects.prefetch_related('device_type__manufacturer')
filterset = filtersets.DeviceFilterSet filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable table = tables.DeviceTable
@ -2398,6 +2466,7 @@ class ModuleListView(generic.ObjectListView):
filterset = filtersets.ModuleFilterSet filterset = filtersets.ModuleFilterSet
filterset_form = forms.ModuleFilterForm filterset_form = forms.ModuleFilterForm
table = tables.ModuleTable table = tables.ModuleTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(Module) @register_model_view(Module)
@ -2453,7 +2522,6 @@ class ConsolePortListView(generic.ObjectListView):
filterset = filtersets.ConsolePortFilterSet filterset = filtersets.ConsolePortFilterSet
filterset_form = forms.ConsolePortFilterForm filterset_form = forms.ConsolePortFilterForm
table = tables.ConsolePortTable table = tables.ConsolePortTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(ConsolePort) @register_model_view(ConsolePort)
@ -2524,7 +2592,6 @@ class ConsoleServerPortListView(generic.ObjectListView):
filterset = filtersets.ConsoleServerPortFilterSet filterset = filtersets.ConsoleServerPortFilterSet
filterset_form = forms.ConsoleServerPortFilterForm filterset_form = forms.ConsoleServerPortFilterForm
table = tables.ConsoleServerPortTable table = tables.ConsoleServerPortTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(ConsoleServerPort) @register_model_view(ConsoleServerPort)
@ -2595,7 +2662,6 @@ class PowerPortListView(generic.ObjectListView):
filterset = filtersets.PowerPortFilterSet filterset = filtersets.PowerPortFilterSet
filterset_form = forms.PowerPortFilterForm filterset_form = forms.PowerPortFilterForm
table = tables.PowerPortTable table = tables.PowerPortTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(PowerPort) @register_model_view(PowerPort)
@ -2666,7 +2732,6 @@ class PowerOutletListView(generic.ObjectListView):
filterset = filtersets.PowerOutletFilterSet filterset = filtersets.PowerOutletFilterSet
filterset_form = forms.PowerOutletFilterForm filterset_form = forms.PowerOutletFilterForm
table = tables.PowerOutletTable table = tables.PowerOutletTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(PowerOutlet) @register_model_view(PowerOutlet)
@ -2737,7 +2802,6 @@ class InterfaceListView(generic.ObjectListView):
filterset = filtersets.InterfaceFilterSet filterset = filtersets.InterfaceFilterSet
filterset_form = forms.InterfaceFilterForm filterset_form = forms.InterfaceFilterForm
table = tables.InterfaceTable table = tables.InterfaceTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(Interface) @register_model_view(Interface)
@ -2881,7 +2945,6 @@ class FrontPortListView(generic.ObjectListView):
filterset = filtersets.FrontPortFilterSet filterset = filtersets.FrontPortFilterSet
filterset_form = forms.FrontPortFilterForm filterset_form = forms.FrontPortFilterForm
table = tables.FrontPortTable table = tables.FrontPortTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(FrontPort) @register_model_view(FrontPort)
@ -2952,7 +3015,6 @@ class RearPortListView(generic.ObjectListView):
filterset = filtersets.RearPortFilterSet filterset = filtersets.RearPortFilterSet
filterset_form = forms.RearPortFilterForm filterset_form = forms.RearPortFilterForm
table = tables.RearPortTable table = tables.RearPortTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(RearPort) @register_model_view(RearPort)
@ -3023,7 +3085,6 @@ class ModuleBayListView(generic.ObjectListView):
filterset = filtersets.ModuleBayFilterSet filterset = filtersets.ModuleBayFilterSet
filterset_form = forms.ModuleBayFilterForm filterset_form = forms.ModuleBayFilterForm
table = tables.ModuleBayTable table = tables.ModuleBayTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(ModuleBay) @register_model_view(ModuleBay)
@ -3085,7 +3146,6 @@ class DeviceBayListView(generic.ObjectListView):
filterset = filtersets.DeviceBayFilterSet filterset = filtersets.DeviceBayFilterSet
filterset_form = forms.DeviceBayFilterForm filterset_form = forms.DeviceBayFilterForm
table = tables.DeviceBayTable table = tables.DeviceBayTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(DeviceBay) @register_model_view(DeviceBay)
@ -3228,7 +3288,6 @@ class InventoryItemListView(generic.ObjectListView):
filterset = filtersets.InventoryItemFilterSet filterset = filtersets.InventoryItemFilterSet
filterset_form = forms.InventoryItemFilterForm filterset_form = forms.InventoryItemFilterForm
table = tables.InventoryItemTable table = tables.InventoryItemTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(InventoryItem) @register_model_view(InventoryItem)
@ -3351,6 +3410,11 @@ class InventoryItemRoleBulkEditView(generic.BulkEditView):
form = forms.InventoryItemRoleBulkEditForm form = forms.InventoryItemRoleBulkEditForm
@register_model_view(InventoryItemRole, 'bulk_rename', path='rename', detail=False)
class InventoryItemRoleBulkRenameView(generic.BulkRenameView):
queryset = InventoryItemRole.objects.all()
@register_model_view(InventoryItemRole, 'bulk_delete', path='delete', detail=False) @register_model_view(InventoryItemRole, 'bulk_delete', path='delete', detail=False)
class InventoryItemRoleBulkDeleteView(generic.BulkDeleteView): class InventoryItemRoleBulkDeleteView(generic.BulkDeleteView):
queryset = InventoryItemRole.objects.annotate( queryset = InventoryItemRole.objects.annotate(
@ -3548,6 +3612,12 @@ class CableBulkEditView(generic.BulkEditView):
form = forms.CableBulkEditForm form = forms.CableBulkEditForm
@register_model_view(Cable, 'bulk_rename', path='rename', detail=False)
class CableBulkRenameView(generic.BulkRenameView):
queryset = Cable.objects.all()
field_name = 'label'
@register_model_view(Cable, 'bulk_delete', path='delete', detail=False) @register_model_view(Cable, 'bulk_delete', path='delete', detail=False)
class CableBulkDeleteView(generic.BulkDeleteView): class CableBulkDeleteView(generic.BulkDeleteView):
queryset = Cable.objects.prefetch_related( queryset = Cable.objects.prefetch_related(
@ -3840,6 +3910,11 @@ class VirtualChassisBulkEditView(generic.BulkEditView):
form = forms.VirtualChassisBulkEditForm form = forms.VirtualChassisBulkEditForm
@register_model_view(VirtualChassis, 'bulk_rename', path='rename', detail=False)
class VirtualChassisBulkRenameView(generic.BulkRenameView):
queryset = VirtualChassis.objects.all()
@register_model_view(VirtualChassis, 'bulk_delete', path='delete', detail=False) @register_model_view(VirtualChassis, 'bulk_delete', path='delete', detail=False)
class VirtualChassisBulkDeleteView(generic.BulkDeleteView): class VirtualChassisBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualChassis.objects.all() queryset = VirtualChassis.objects.all()
@ -3897,6 +3972,11 @@ class PowerPanelBulkEditView(generic.BulkEditView):
form = forms.PowerPanelBulkEditForm form = forms.PowerPanelBulkEditForm
@register_model_view(PowerPanel, 'bulk_rename', path='rename', detail=False)
class PowerPanelBulkRenameView(generic.BulkRenameView):
queryset = PowerPanel.objects.all()
@register_model_view(PowerPanel, 'bulk_delete', path='delete', detail=False) @register_model_view(PowerPanel, 'bulk_delete', path='delete', detail=False)
class PowerPanelBulkDeleteView(generic.BulkDeleteView): class PowerPanelBulkDeleteView(generic.BulkDeleteView):
queryset = PowerPanel.objects.annotate( queryset = PowerPanel.objects.annotate(
@ -3949,6 +4029,11 @@ class PowerFeedBulkEditView(generic.BulkEditView):
form = forms.PowerFeedBulkEditForm form = forms.PowerFeedBulkEditForm
@register_model_view(PowerFeed, 'bulk_rename', path='rename', detail=False)
class PowerFeedBulkRenameView(generic.BulkRenameView):
queryset = PowerFeed.objects.all()
@register_model_view(PowerFeed, 'bulk_disconnect', path='disconnect', detail=False) @register_model_view(PowerFeed, 'bulk_disconnect', path='disconnect', detail=False)
class PowerFeedBulkDisconnectView(BulkDisconnectView): class PowerFeedBulkDisconnectView(BulkDisconnectView):
queryset = PowerFeed.objects.all() queryset = PowerFeed.objects.all()
@ -3977,6 +4062,7 @@ class VirtualDeviceContextListView(generic.ObjectListView):
filterset = filtersets.VirtualDeviceContextFilterSet filterset = filtersets.VirtualDeviceContextFilterSet
filterset_form = forms.VirtualDeviceContextFilterForm filterset_form = forms.VirtualDeviceContextFilterForm
table = tables.VirtualDeviceContextTable table = tables.VirtualDeviceContextTable
actions = (AddObject, BulkImport, BulkEdit, BulkRename, BulkExport, BulkDelete)
@register_model_view(VirtualDeviceContext) @register_model_view(VirtualDeviceContext)
@ -4021,6 +4107,11 @@ class VirtualDeviceContextBulkEditView(generic.BulkEditView):
form = forms.VirtualDeviceContextBulkEditForm form = forms.VirtualDeviceContextBulkEditForm
@register_model_view(VirtualDeviceContext, 'bulk_rename', path='rename', detail=False)
class VirtualDeviceContextBulkRenameView(generic.BulkRenameView):
queryset = VirtualDeviceContext.objects.all()
@register_model_view(VirtualDeviceContext, 'bulk_delete', path='delete', detail=False) @register_model_view(VirtualDeviceContext, 'bulk_delete', path='delete', detail=False)
class VirtualDeviceContextBulkDeleteView(generic.BulkDeleteView): class VirtualDeviceContextBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualDeviceContext.objects.all() queryset = VirtualDeviceContext.objects.all()
@ -4038,6 +4129,7 @@ class MACAddressListView(generic.ObjectListView):
filterset = filtersets.MACAddressFilterSet filterset = filtersets.MACAddressFilterSet
filterset_form = forms.MACAddressFilterForm filterset_form = forms.MACAddressFilterForm
table = tables.MACAddressTable table = tables.MACAddressTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(MACAddress) @register_model_view(MACAddress)

View File

@ -97,6 +97,11 @@ class CustomFieldBulkEditView(generic.BulkEditView):
form = forms.CustomFieldBulkEditForm form = forms.CustomFieldBulkEditForm
@register_model_view(CustomField, 'bulk_rename', path='rename', detail=False)
class CustomFieldBulkRenameView(generic.BulkRenameView):
queryset = CustomField.objects.all()
@register_model_view(CustomField, 'bulk_delete', path='delete', detail=False) @register_model_view(CustomField, 'bulk_delete', path='delete', detail=False)
class CustomFieldBulkDeleteView(generic.BulkDeleteView): class CustomFieldBulkDeleteView(generic.BulkDeleteView):
queryset = CustomField.objects.select_related('choice_set') queryset = CustomField.objects.select_related('choice_set')
@ -166,6 +171,11 @@ class CustomFieldChoiceSetBulkEditView(generic.BulkEditView):
form = forms.CustomFieldChoiceSetBulkEditForm form = forms.CustomFieldChoiceSetBulkEditForm
@register_model_view(CustomFieldChoiceSet, 'bulk_rename', path='rename', detail=False)
class CustomFieldChoiceSetBulkRenameView(generic.BulkRenameView):
queryset = CustomFieldChoiceSet.objects.all()
@register_model_view(CustomFieldChoiceSet, 'bulk_delete', path='delete', detail=False) @register_model_view(CustomFieldChoiceSet, 'bulk_delete', path='delete', detail=False)
class CustomFieldChoiceSetBulkDeleteView(generic.BulkDeleteView): class CustomFieldChoiceSetBulkDeleteView(generic.BulkDeleteView):
queryset = CustomFieldChoiceSet.objects.all() queryset = CustomFieldChoiceSet.objects.all()
@ -216,6 +226,11 @@ class CustomLinkBulkEditView(generic.BulkEditView):
form = forms.CustomLinkBulkEditForm form = forms.CustomLinkBulkEditForm
@register_model_view(CustomLink, 'bulk_rename', path='rename', detail=False)
class CustomLinkBulkRenameView(generic.BulkRenameView):
queryset = CustomLink.objects.all()
@register_model_view(CustomLink, 'bulk_delete', path='delete', detail=False) @register_model_view(CustomLink, 'bulk_delete', path='delete', detail=False)
class CustomLinkBulkDeleteView(generic.BulkDeleteView): class CustomLinkBulkDeleteView(generic.BulkDeleteView):
queryset = CustomLink.objects.all() queryset = CustomLink.objects.all()
@ -233,7 +248,7 @@ class ExportTemplateListView(generic.ObjectListView):
filterset = filtersets.ExportTemplateFilterSet filterset = filtersets.ExportTemplateFilterSet
filterset_form = forms.ExportTemplateFilterForm filterset_form = forms.ExportTemplateFilterForm
table = tables.ExportTemplateTable table = tables.ExportTemplateTable
actions = (AddObject, BulkImport, BulkSync, BulkEdit, BulkExport, BulkDelete) actions = (AddObject, BulkImport, BulkSync, BulkExport, BulkEdit, BulkRename, BulkDelete)
@register_model_view(ExportTemplate) @register_model_view(ExportTemplate)
@ -267,6 +282,11 @@ class ExportTemplateBulkEditView(generic.BulkEditView):
form = forms.ExportTemplateBulkEditForm form = forms.ExportTemplateBulkEditForm
@register_model_view(ExportTemplate, 'bulk_rename', path='rename', detail=False)
class ExportTemplateBulkRenameView(generic.BulkRenameView):
queryset = ExportTemplate.objects.all()
@register_model_view(ExportTemplate, 'bulk_delete', path='delete', detail=False) @register_model_view(ExportTemplate, 'bulk_delete', path='delete', detail=False)
class ExportTemplateBulkDeleteView(generic.BulkDeleteView): class ExportTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ExportTemplate.objects.all() queryset = ExportTemplate.objects.all()
@ -327,6 +347,11 @@ class SavedFilterBulkEditView(SharedObjectViewMixin, generic.BulkEditView):
form = forms.SavedFilterBulkEditForm form = forms.SavedFilterBulkEditForm
@register_model_view(SavedFilter, 'bulk_rename', path='rename', detail=False)
class SavedFilterBulkRenameView(generic.BulkRenameView):
queryset = SavedFilter.objects.all()
@register_model_view(SavedFilter, 'bulk_delete', path='delete', detail=False) @register_model_view(SavedFilter, 'bulk_delete', path='delete', detail=False)
class SavedFilterBulkDeleteView(SharedObjectViewMixin, generic.BulkDeleteView): class SavedFilterBulkDeleteView(SharedObjectViewMixin, generic.BulkDeleteView):
queryset = SavedFilter.objects.all() queryset = SavedFilter.objects.all()
@ -344,7 +369,7 @@ class TableConfigListView(SharedObjectViewMixin, generic.ObjectListView):
filterset = filtersets.TableConfigFilterSet filterset = filtersets.TableConfigFilterSet
filterset_form = forms.TableConfigFilterForm filterset_form = forms.TableConfigFilterForm
table = tables.TableConfigTable table = tables.TableConfigTable
actions = (BulkExport,) actions = (BulkExport, BulkEdit, BulkRename, BulkDelete)
@register_model_view(TableConfig) @register_model_view(TableConfig)
@ -384,6 +409,11 @@ class TableConfigBulkEditView(SharedObjectViewMixin, generic.BulkEditView):
form = forms.TableConfigBulkEditForm form = forms.TableConfigBulkEditForm
@register_model_view(TableConfig, 'bulk_rename', path='rename', detail=False)
class TableConfigBulkRenameView(generic.BulkRenameView):
queryset = TableConfig.objects.all()
@register_model_view(TableConfig, 'bulk_delete', path='delete', detail=False) @register_model_view(TableConfig, 'bulk_delete', path='delete', detail=False)
class TableConfigBulkDeleteView(SharedObjectViewMixin, generic.BulkDeleteView): class TableConfigBulkDeleteView(SharedObjectViewMixin, generic.BulkDeleteView):
queryset = TableConfig.objects.all() queryset = TableConfig.objects.all()
@ -465,6 +495,11 @@ class NotificationGroupBulkEditView(generic.BulkEditView):
form = forms.NotificationGroupBulkEditForm form = forms.NotificationGroupBulkEditForm
@register_model_view(NotificationGroup, 'bulk_rename', path='rename', detail=False)
class NotificationGroupBulkRenameView(generic.BulkRenameView):
queryset = NotificationGroup.objects.all()
@register_model_view(NotificationGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(NotificationGroup, 'bulk_delete', path='delete', detail=False)
class NotificationGroupBulkDeleteView(generic.BulkDeleteView): class NotificationGroupBulkDeleteView(generic.BulkDeleteView):
queryset = NotificationGroup.objects.all() queryset = NotificationGroup.objects.all()
@ -611,6 +646,11 @@ class WebhookBulkEditView(generic.BulkEditView):
form = forms.WebhookBulkEditForm form = forms.WebhookBulkEditForm
@register_model_view(Webhook, 'bulk_rename', path='rename', detail=False)
class WebhookBulkRenameView(generic.BulkRenameView):
queryset = Webhook.objects.all()
@register_model_view(Webhook, 'bulk_delete', path='delete', detail=False) @register_model_view(Webhook, 'bulk_delete', path='delete', detail=False)
class WebhookBulkDeleteView(generic.BulkDeleteView): class WebhookBulkDeleteView(generic.BulkDeleteView):
queryset = Webhook.objects.all() queryset = Webhook.objects.all()
@ -661,6 +701,11 @@ class EventRuleBulkEditView(generic.BulkEditView):
form = forms.EventRuleBulkEditForm form = forms.EventRuleBulkEditForm
@register_model_view(EventRule, 'bulk_rename', path='rename', detail=False)
class EventRuleBulkRenameView(generic.BulkRenameView):
queryset = EventRule.objects.all()
@register_model_view(EventRule, 'bulk_delete', path='delete', detail=False) @register_model_view(EventRule, 'bulk_delete', path='delete', detail=False)
class EventRuleBulkDeleteView(generic.BulkDeleteView): class EventRuleBulkDeleteView(generic.BulkDeleteView):
queryset = EventRule.objects.all() queryset = EventRule.objects.all()
@ -735,6 +780,11 @@ class TagBulkEditView(generic.BulkEditView):
form = forms.TagBulkEditForm form = forms.TagBulkEditForm
@register_model_view(Tag, 'bulk_rename', path='rename', detail=False)
class TagBulkRenameView(generic.BulkRenameView):
queryset = Tag.objects.all()
@register_model_view(Tag, 'bulk_delete', path='delete', detail=False) @register_model_view(Tag, 'bulk_delete', path='delete', detail=False)
class TagBulkDeleteView(generic.BulkDeleteView): class TagBulkDeleteView(generic.BulkDeleteView):
queryset = Tag.objects.annotate( queryset = Tag.objects.annotate(
@ -753,7 +803,7 @@ class ConfigContextListView(generic.ObjectListView):
filterset = filtersets.ConfigContextFilterSet filterset = filtersets.ConfigContextFilterSet
filterset_form = forms.ConfigContextFilterForm filterset_form = forms.ConfigContextFilterForm
table = tables.ConfigContextTable table = tables.ConfigContextTable
actions = (AddObject, BulkSync, BulkEdit, BulkDelete) actions = (AddObject, BulkSync, BulkEdit, BulkRename, BulkDelete)
@register_model_view(ConfigContext) @register_model_view(ConfigContext)
@ -814,6 +864,11 @@ class ConfigContextBulkEditView(generic.BulkEditView):
form = forms.ConfigContextBulkEditForm form = forms.ConfigContextBulkEditForm
@register_model_view(ConfigContext, 'bulk_rename', path='rename', detail=False)
class ConfigContextBulkRenameView(generic.BulkRenameView):
queryset = ConfigContext.objects.all()
@register_model_view(ConfigContext, 'bulk_delete', path='delete', detail=False) @register_model_view(ConfigContext, 'bulk_delete', path='delete', detail=False)
class ConfigContextBulkDeleteView(generic.BulkDeleteView): class ConfigContextBulkDeleteView(generic.BulkDeleteView):
queryset = ConfigContext.objects.all() queryset = ConfigContext.objects.all()
@ -866,7 +921,7 @@ class ConfigTemplateListView(generic.ObjectListView):
filterset = filtersets.ConfigTemplateFilterSet filterset = filtersets.ConfigTemplateFilterSet
filterset_form = forms.ConfigTemplateFilterForm filterset_form = forms.ConfigTemplateFilterForm
table = tables.ConfigTemplateTable table = tables.ConfigTemplateTable
actions = (AddObject, BulkImport, BulkSync, BulkEdit, BulkExport, BulkDelete) actions = (AddObject, BulkImport, BulkExport, BulkSync, BulkEdit, BulkRename, BulkDelete)
@register_model_view(ConfigTemplate) @register_model_view(ConfigTemplate)
@ -900,6 +955,11 @@ class ConfigTemplateBulkEditView(generic.BulkEditView):
form = forms.ConfigTemplateBulkEditForm form = forms.ConfigTemplateBulkEditForm
@register_model_view(ConfigTemplate, 'bulk_rename', path='rename', detail=False)
class ConfigTemplateBulkRenameView(generic.BulkRenameView):
queryset = ConfigTemplate.objects.all()
@register_model_view(ConfigTemplate, 'bulk_delete', path='delete', detail=False) @register_model_view(ConfigTemplate, 'bulk_delete', path='delete', detail=False)
class ConfigTemplateBulkDeleteView(generic.BulkDeleteView): class ConfigTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ConfigTemplate.objects.all() queryset = ConfigTemplate.objects.all()

View File

@ -10,6 +10,7 @@ from dcim.filtersets import InterfaceFilterSet
from dcim.forms import InterfaceFilterForm from dcim.forms import InterfaceFilterForm
from dcim.models import Device, Interface, Site from dcim.models import Device, Interface, Site
from ipam.tables import VLANTranslationRuleTable from ipam.tables import VLANTranslationRuleTable
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport
from netbox.views import generic from netbox.views import generic
from utilities.query import count_related from utilities.query import count_related
from utilities.tables import get_table_ordering from utilities.tables import get_table_ordering
@ -86,6 +87,11 @@ class VRFBulkEditView(generic.BulkEditView):
form = forms.VRFBulkEditForm form = forms.VRFBulkEditForm
@register_model_view(VRF, 'bulk_rename', path='rename', detail=False)
class VRFBulkRenameView(generic.BulkRenameView):
queryset = VRF.objects.all()
@register_model_view(VRF, 'bulk_delete', path='delete', detail=False) @register_model_view(VRF, 'bulk_delete', path='delete', detail=False)
class VRFBulkDeleteView(generic.BulkDeleteView): class VRFBulkDeleteView(generic.BulkDeleteView):
queryset = VRF.objects.all() queryset = VRF.objects.all()
@ -136,6 +142,11 @@ class RouteTargetBulkEditView(generic.BulkEditView):
form = forms.RouteTargetBulkEditForm form = forms.RouteTargetBulkEditForm
@register_model_view(RouteTarget, 'bulk_rename', path='rename', detail=False)
class RouteTargetBulkRenameView(generic.BulkRenameView):
queryset = RouteTarget.objects.all()
@register_model_view(RouteTarget, 'bulk_delete', path='delete', detail=False) @register_model_view(RouteTarget, 'bulk_delete', path='delete', detail=False)
class RouteTargetBulkDeleteView(generic.BulkDeleteView): class RouteTargetBulkDeleteView(generic.BulkDeleteView):
queryset = RouteTarget.objects.all() queryset = RouteTarget.objects.all()
@ -195,6 +206,11 @@ class RIRBulkEditView(generic.BulkEditView):
form = forms.RIRBulkEditForm form = forms.RIRBulkEditForm
@register_model_view(RIR, 'bulk_rename', path='rename', detail=False)
class RIRBulkRenameView(generic.BulkRenameView):
queryset = RIR.objects.all()
@register_model_view(RIR, 'bulk_delete', path='delete', detail=False) @register_model_view(RIR, 'bulk_delete', path='delete', detail=False)
class RIRBulkDeleteView(generic.BulkDeleteView): class RIRBulkDeleteView(generic.BulkDeleteView):
queryset = RIR.objects.annotate( queryset = RIR.objects.annotate(
@ -268,6 +284,11 @@ class ASNRangeBulkEditView(generic.BulkEditView):
form = forms.ASNRangeBulkEditForm form = forms.ASNRangeBulkEditForm
@register_model_view(ASNRange, 'bulk_rename', path='rename', detail=False)
class ASNRangeBulkRenameView(generic.BulkRenameView):
queryset = ASNRange.objects.all()
@register_model_view(ASNRange, 'bulk_delete', path='delete', detail=False) @register_model_view(ASNRange, 'bulk_delete', path='delete', detail=False)
class ASNRangeBulkDeleteView(generic.BulkDeleteView): class ASNRangeBulkDeleteView(generic.BulkDeleteView):
queryset = ASNRange.objects.annotate_asn_counts() queryset = ASNRange.objects.annotate_asn_counts()
@ -335,6 +356,11 @@ class ASNBulkEditView(generic.BulkEditView):
form = forms.ASNBulkEditForm form = forms.ASNBulkEditForm
@register_model_view(ASN, 'bulk_rename', path='rename', detail=False)
class ASNBulkRenameView(generic.BulkRenameView):
queryset = ASN.objects.all()
@register_model_view(ASN, 'bulk_delete', path='delete', detail=False) @register_model_view(ASN, 'bulk_delete', path='delete', detail=False)
class ASNBulkDeleteView(generic.BulkDeleteView): class ASNBulkDeleteView(generic.BulkDeleteView):
queryset = ASN.objects.annotate( queryset = ASN.objects.annotate(
@ -356,6 +382,7 @@ class AggregateListView(generic.ObjectListView):
filterset = filtersets.AggregateFilterSet filterset = filtersets.AggregateFilterSet
filterset_form = forms.AggregateFilterForm filterset_form = forms.AggregateFilterForm
table = tables.AggregateTable table = tables.AggregateTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(Aggregate) @register_model_view(Aggregate)
@ -488,6 +515,11 @@ class RoleBulkEditView(generic.BulkEditView):
form = forms.RoleBulkEditForm form = forms.RoleBulkEditForm
@register_model_view(Role, 'bulk_rename', path='rename', detail=False)
class RoleBulkRenameView(generic.BulkRenameView):
queryset = Role.objects.all()
@register_model_view(Role, 'bulk_delete', path='delete', detail=False) @register_model_view(Role, 'bulk_delete', path='delete', detail=False)
class RoleBulkDeleteView(generic.BulkDeleteView): class RoleBulkDeleteView(generic.BulkDeleteView):
queryset = Role.objects.all() queryset = Role.objects.all()
@ -506,6 +538,7 @@ class PrefixListView(generic.ObjectListView):
filterset_form = forms.PrefixFilterForm filterset_form = forms.PrefixFilterForm
table = tables.PrefixTable table = tables.PrefixTable
template_name = 'ipam/prefix_list.html' template_name = 'ipam/prefix_list.html'
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(Prefix) @register_model_view(Prefix)
@ -766,6 +799,11 @@ class IPRangeBulkEditView(generic.BulkEditView):
form = forms.IPRangeBulkEditForm form = forms.IPRangeBulkEditForm
@register_model_view(IPRange, 'bulk_rename', path='rename', detail=False)
class IPRangeBulkRenameView(generic.BulkRenameView):
queryset = IPRange.objects.all()
@register_model_view(IPRange, 'bulk_delete', path='delete', detail=False) @register_model_view(IPRange, 'bulk_delete', path='delete', detail=False)
class IPRangeBulkDeleteView(generic.BulkDeleteView): class IPRangeBulkDeleteView(generic.BulkDeleteView):
queryset = IPRange.objects.all() queryset = IPRange.objects.all()
@ -783,6 +821,7 @@ class IPAddressListView(generic.ObjectListView):
filterset = filtersets.IPAddressFilterSet filterset = filtersets.IPAddressFilterSet
filterset_form = forms.IPAddressFilterForm filterset_form = forms.IPAddressFilterForm
table = tables.IPAddressTable table = tables.IPAddressTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(IPAddress) @register_model_view(IPAddress)
@ -1006,6 +1045,11 @@ class VLANGroupBulkEditView(generic.BulkEditView):
form = forms.VLANGroupBulkEditForm form = forms.VLANGroupBulkEditForm
@register_model_view(VLANGroup, 'bulk_rename', path='rename', detail=False)
class VLANGroupBulkRenameView(generic.BulkRenameView):
queryset = VLANGroup.objects.all()
@register_model_view(VLANGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(VLANGroup, 'bulk_delete', path='delete', detail=False)
class VLANGroupBulkDeleteView(generic.BulkDeleteView): class VLANGroupBulkDeleteView(generic.BulkDeleteView):
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags') queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
@ -1095,6 +1139,11 @@ class VLANTranslationPolicyBulkEditView(generic.BulkEditView):
form = forms.VLANTranslationPolicyBulkEditForm form = forms.VLANTranslationPolicyBulkEditForm
@register_model_view(VLANTranslationPolicy, 'bulk_rename', path='rename', detail=False)
class VLANTranslationPolicyBulkRenameView(generic.BulkRenameView):
queryset = VLANTranslationPolicy.objects.all()
@register_model_view(VLANTranslationPolicy, 'bulk_delete', path='delete', detail=False) @register_model_view(VLANTranslationPolicy, 'bulk_delete', path='delete', detail=False)
class VLANTranslationPolicyBulkDeleteView(generic.BulkDeleteView): class VLANTranslationPolicyBulkDeleteView(generic.BulkDeleteView):
queryset = VLANTranslationPolicy.objects.all() queryset = VLANTranslationPolicy.objects.all()
@ -1112,6 +1161,7 @@ class VLANTranslationRuleListView(generic.ObjectListView):
filterset = filtersets.VLANTranslationRuleFilterSet filterset = filtersets.VLANTranslationRuleFilterSet
filterset_form = forms.VLANTranslationRuleFilterForm filterset_form = forms.VLANTranslationRuleFilterForm
table = tables.VLANTranslationRuleTable table = tables.VLANTranslationRuleTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(VLANTranslationRule) @register_model_view(VLANTranslationRule)
@ -1244,6 +1294,11 @@ class FHRPGroupBulkEditView(generic.BulkEditView):
form = forms.FHRPGroupBulkEditForm form = forms.FHRPGroupBulkEditForm
@register_model_view(FHRPGroup, 'bulk_rename', path='rename', detail=False)
class FHRPGroupBulkRenameView(generic.BulkRenameView):
queryset = FHRPGroup.objects.all()
@register_model_view(FHRPGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(FHRPGroup, 'bulk_delete', path='delete', detail=False)
class FHRPGroupBulkDeleteView(generic.BulkDeleteView): class FHRPGroupBulkDeleteView(generic.BulkDeleteView):
queryset = FHRPGroup.objects.all() queryset = FHRPGroup.objects.all()
@ -1371,6 +1426,11 @@ class VLANBulkEditView(generic.BulkEditView):
form = forms.VLANBulkEditForm form = forms.VLANBulkEditForm
@register_model_view(VLAN, 'bulk_rename', path='rename', detail=False)
class VLANBulkRenameView(generic.BulkRenameView):
queryset = VLAN.objects.all()
@register_model_view(VLAN, 'bulk_delete', path='delete', detail=False) @register_model_view(VLAN, 'bulk_delete', path='delete', detail=False)
class VLANBulkDeleteView(generic.BulkDeleteView): class VLANBulkDeleteView(generic.BulkDeleteView):
queryset = VLAN.objects.all() queryset = VLAN.objects.all()
@ -1421,6 +1481,11 @@ class ServiceTemplateBulkEditView(generic.BulkEditView):
form = forms.ServiceTemplateBulkEditForm form = forms.ServiceTemplateBulkEditForm
@register_model_view(ServiceTemplate, 'bulk_rename', path='rename', detail=False)
class ServiceTemplateBulkRenameView(generic.BulkRenameView):
queryset = ServiceTemplate.objects.all()
@register_model_view(ServiceTemplate, 'bulk_delete', path='delete', detail=False) @register_model_view(ServiceTemplate, 'bulk_delete', path='delete', detail=False)
class ServiceTemplateBulkDeleteView(generic.BulkDeleteView): class ServiceTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ServiceTemplate.objects.all() queryset = ServiceTemplate.objects.all()
@ -1488,6 +1553,11 @@ class ServiceBulkEditView(generic.BulkEditView):
form = forms.ServiceBulkEditForm form = forms.ServiceBulkEditForm
@register_model_view(Service, 'bulk_rename', path='rename', detail=False)
class ServiceBulkRenameView(generic.BulkRenameView):
queryset = Service.objects.all()
@register_model_view(Service, 'bulk_delete', path='delete', detail=False) @register_model_view(Service, 'bulk_delete', path='delete', detail=False)
class ServiceBulkDeleteView(generic.BulkDeleteView): class ServiceBulkDeleteView(generic.BulkDeleteView):
queryset = Service.objects.prefetch_related('parent') queryset = Service.objects.prefetch_related('parent')

View File

@ -1,4 +1,5 @@
from django.urls import reverse from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from core.models import ObjectType from core.models import ObjectType
@ -42,7 +43,10 @@ class ObjectAction:
kwargs = { kwargs = {
kwarg: getattr(obj, kwarg) for kwarg in cls.url_kwargs kwarg: getattr(obj, kwarg) for kwarg in cls.url_kwargs
} }
return reverse(viewname, kwargs=kwargs) try:
return reverse(viewname, kwargs=kwargs)
except NoReverseMatch:
return
@classmethod @classmethod
def get_context(cls, context, obj): def get_context(cls, context, obj):

View File

@ -22,7 +22,7 @@ from core.models import ObjectType
from core.signals import clear_events from core.signals import clear_events
from extras.choices import CustomFieldUIEditableChoices from extras.choices import CustomFieldUIEditableChoices
from extras.models import CustomField, ExportTemplate from extras.models import CustomField, ExportTemplate
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
from utilities.error_handlers import handle_protectederror from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
@ -55,13 +55,12 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
Attributes: Attributes:
filterset: A django-filter FilterSet that is applied to the queryset filterset: A django-filter FilterSet that is applied to the queryset
filterset_form: The form class used to render filter options filterset_form: The form class used to render filter options
actions: A mapping of supported actions to their required permissions. When adding custom actions, bulk actions: An iterable of ObjectAction subclasses (see ActionsMixin)
action names must be prefixed with `bulk_`. (See ActionsMixin.)
""" """
template_name = 'generic/object_list.html' template_name = 'generic/object_list.html'
filterset = None filterset = None
filterset_form = None filterset_form = None
actions = (AddObject, BulkImport, BulkEdit, BulkExport, BulkDelete) actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkRename, BulkDelete)
def get_required_permission(self): def get_required_permission(self):
return get_permission_for_model(self.queryset.model, 'view') return get_permission_for_model(self.queryset.model, 'view')
@ -731,7 +730,11 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView): class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView):
""" """
An extendable view for renaming objects in bulk. An extendable view for renaming objects in bulk.
Attributes:
field_name: The name of the object attribute for which the value is being updated (defaults to "name")
""" """
field_name = 'name'
template_name = 'generic/bulk_rename.html' template_name = 'generic/bulk_rename.html'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -761,12 +764,12 @@ class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView):
replace = form.cleaned_data['replace'] replace = form.cleaned_data['replace']
if form.cleaned_data['use_regex']: if form.cleaned_data['use_regex']:
try: try:
obj.new_name = re.sub(find, replace, obj.name or '') obj.new_name = re.sub(find, replace, getattr(obj, self.field_name, ''))
# Catch regex group reference errors # Catch regex group reference errors
except re.error: except re.error:
obj.new_name = obj.name obj.new_name = getattr(obj, self.field_name)
else: else:
obj.new_name = (obj.name or '').replace(find, replace) obj.new_name = getattr(obj, self.field_name, '').replace(find, replace)
renamed_pks.append(obj.pk) renamed_pks.append(obj.pk)
return renamed_pks return renamed_pks
@ -785,7 +788,7 @@ class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView):
if '_apply' in request.POST: if '_apply' in request.POST:
for obj in selected_objects: for obj in selected_objects:
obj.name = obj.new_name setattr(obj, self.field_name, obj.new_name)
obj.save() obj.save()
# Enforce constrained permissions # Enforce constrained permissions
@ -815,6 +818,7 @@ class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView):
selected_objects = self.queryset.filter(pk__in=form.initial['pk']) selected_objects = self.queryset.filter(pk__in=form.initial['pk'])
return render(request, self.template_name, { return render(request, self.template_name, {
'field_name': self.field_name,
'form': form, 'form': form,
'obj_type_plural': self.queryset.model._meta.verbose_name_plural, 'obj_type_plural': self.queryset.model._meta.verbose_name_plural,
'selected_objects': selected_objects, 'selected_objects': selected_objects,

View File

@ -47,6 +47,7 @@ class ObjectView(ActionsMixin, BaseObjectView):
Attributes: Attributes:
tab: A ViewTab instance for the view tab: A ViewTab instance for the view
actions: An iterable of ObjectAction subclasses (see ActionsMixin)
""" """
tab = None tab = None
actions = (CloneObject, EditObject, DeleteObject) actions = (CloneObject, EditObject, DeleteObject)
@ -96,8 +97,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
table: The django-tables2 Table class used to render the child objects list table: The django-tables2 Table class used to render the child objects list
filterset: A django-filter FilterSet that is applied to the queryset filterset: A django-filter FilterSet that is applied to the queryset
filterset_form: The form class used to render filter options filterset_form: The form class used to render filter options
actions: A mapping of supported actions to their required permissions. When adding custom actions, bulk actions: An iterable of ObjectAction subclasses (see ActionsMixin)
action names must be prefixed with `bulk_`. (See ActionsMixin.)
""" """
child_model = None child_model = None
table = None table = None

View File

@ -42,10 +42,12 @@ Context:
</thead> </thead>
<tbody> <tbody>
{% for obj in selected_objects %} {% for obj in selected_objects %}
<tr{% if obj.new_name and obj.name != obj.new_name %} class="success"{% endif %}> {% with obj_name=obj|getattr:field_name %}
<td>{{ obj.name }}</td> <tr{% if obj.new_name and obj_name != obj.new_name %} class="success"{% endif %}>
<td>{{ obj.new_name }}</td> <td>{{ obj_name }}</td>
</tr> <td>{{ obj.new_name }}</td>
</tr>
{% endwith %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>

View File

@ -27,12 +27,7 @@
{# Update the bulk action buttons with new query parameters #} {# Update the bulk action buttons with new query parameters #}
{% if actions %} {% if actions %}
<div class="bulk-action-buttons" hx-swap-oob="outerHTML:.bulk-action-buttons"> <div class="bulk-action-buttons" hx-swap-oob="outerHTML:.bulk-action-buttons">
{% if 'bulk_edit' in actions %} {% action_buttons actions model multi=True %}
{% bulk_edit_button model query_params=request.GET %}
{% endif %}
{% if 'bulk_delete' in actions %}
{% bulk_delete_button model query_params=request.GET %}
{% endif %}
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -71,6 +71,11 @@ class TenantGroupBulkEditView(generic.BulkEditView):
form = forms.TenantGroupBulkEditForm form = forms.TenantGroupBulkEditForm
@register_model_view(TenantGroup, 'bulk_rename', path='rename', detail=False)
class TenantGroupBulkRenameView(generic.BulkRenameView):
queryset = TenantGroup.objects.all()
@register_model_view(TenantGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(TenantGroup, 'bulk_delete', path='delete', detail=False)
class TenantGroupBulkDeleteView(generic.BulkDeleteView): class TenantGroupBulkDeleteView(generic.BulkDeleteView):
queryset = TenantGroup.objects.add_related_count( queryset = TenantGroup.objects.add_related_count(
@ -132,6 +137,11 @@ class TenantBulkEditView(generic.BulkEditView):
form = forms.TenantBulkEditForm form = forms.TenantBulkEditForm
@register_model_view(Tenant, 'bulk_rename', path='rename', detail=False)
class TenantBulkRenameView(generic.BulkRenameView):
queryset = Tenant.objects.all()
@register_model_view(Tenant, 'bulk_delete', path='delete', detail=False) @register_model_view(Tenant, 'bulk_delete', path='delete', detail=False)
class TenantBulkDeleteView(generic.BulkDeleteView): class TenantBulkDeleteView(generic.BulkDeleteView):
queryset = Tenant.objects.all() queryset = Tenant.objects.all()
@ -207,6 +217,11 @@ class ContactGroupBulkEditView(generic.BulkEditView):
form = forms.ContactGroupBulkEditForm form = forms.ContactGroupBulkEditForm
@register_model_view(ContactGroup, 'bulk_rename', path='rename', detail=False)
class ContactGroupBulkRenameView(generic.BulkRenameView):
queryset = ContactGroup.objects.all()
@register_model_view(ContactGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(ContactGroup, 'bulk_delete', path='delete', detail=False)
class ContactGroupBulkDeleteView(generic.BulkDeleteView): class ContactGroupBulkDeleteView(generic.BulkDeleteView):
queryset = ContactGroup.objects.add_related_count( queryset = ContactGroup.objects.add_related_count(
@ -268,6 +283,11 @@ class ContactRoleBulkEditView(generic.BulkEditView):
form = forms.ContactRoleBulkEditForm form = forms.ContactRoleBulkEditForm
@register_model_view(ContactRole, 'bulk_rename', path='rename', detail=False)
class ContactRoleBulkRenameView(generic.BulkRenameView):
queryset = ContactRole.objects.all()
@register_model_view(ContactRole, 'bulk_delete', path='delete', detail=False) @register_model_view(ContactRole, 'bulk_delete', path='delete', detail=False)
class ContactRoleBulkDeleteView(generic.BulkDeleteView): class ContactRoleBulkDeleteView(generic.BulkDeleteView):
queryset = ContactRole.objects.all() queryset = ContactRole.objects.all()
@ -331,6 +351,11 @@ class ContactBulkEditView(generic.BulkEditView):
obj.groups.remove(*form.cleaned_data['remove_groups']) obj.groups.remove(*form.cleaned_data['remove_groups'])
@register_model_view(Contact, 'bulk_rename', path='rename', detail=False)
class ContactBulkRenameView(generic.BulkRenameView):
queryset = Contact.objects.all()
@register_model_view(Contact, 'bulk_delete', path='delete', detail=False) @register_model_view(Contact, 'bulk_delete', path='delete', detail=False)
class ContactBulkDeleteView(generic.BulkDeleteView): class ContactBulkDeleteView(generic.BulkDeleteView):
queryset = Contact.objects.annotate( queryset = Contact.objects.annotate(

View File

@ -2,6 +2,7 @@ from django.db.models import Count
from core.models import ObjectChange from core.models import ObjectChange
from core.tables import ObjectChangeTable from core.tables import ObjectChangeTable
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename
from netbox.views import generic from netbox.views import generic
from utilities.views import register_model_view from utilities.views import register_model_view
from . import filtersets, forms, tables from . import filtersets, forms, tables
@ -18,6 +19,7 @@ class TokenListView(generic.ObjectListView):
filterset = filtersets.TokenFilterSet filterset = filtersets.TokenFilterSet
filterset_form = forms.TokenFilterForm filterset_form = forms.TokenFilterForm
table = tables.TokenTable table = tables.TokenTable
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(Token) @register_model_view(Token)
@ -111,6 +113,12 @@ class UserBulkEditView(generic.BulkEditView):
form = forms.UserBulkEditForm form = forms.UserBulkEditForm
@register_model_view(User, 'bulk_rename', path='rename', detail=False)
class UserBulkRenameView(generic.BulkRenameView):
queryset = User.objects.all()
field_name = 'username'
@register_model_view(User, 'bulk_delete', path='delete', detail=False) @register_model_view(User, 'bulk_delete', path='delete', detail=False)
class UserBulkDeleteView(generic.BulkDeleteView): class UserBulkDeleteView(generic.BulkDeleteView):
queryset = User.objects.all() queryset = User.objects.all()
@ -162,6 +170,11 @@ class GroupBulkEditView(generic.BulkEditView):
form = forms.GroupBulkEditForm form = forms.GroupBulkEditForm
@register_model_view(Group, 'bulk_rename', path='rename', detail=False)
class GroupBulkRenameView(generic.BulkRenameView):
queryset = Group.objects.all()
@register_model_view(Group, 'bulk_delete', path='delete', detail=False) @register_model_view(Group, 'bulk_delete', path='delete', detail=False)
class GroupBulkDeleteView(generic.BulkDeleteView): class GroupBulkDeleteView(generic.BulkDeleteView):
queryset = Group.objects.annotate(users_count=Count('user')).order_by('name') queryset = Group.objects.annotate(users_count=Count('user')).order_by('name')
@ -179,6 +192,7 @@ class ObjectPermissionListView(generic.ObjectListView):
filterset = filtersets.ObjectPermissionFilterSet filterset = filtersets.ObjectPermissionFilterSet
filterset_form = forms.ObjectPermissionFilterForm filterset_form = forms.ObjectPermissionFilterForm
table = tables.ObjectPermissionTable table = tables.ObjectPermissionTable
actions = (AddObject, BulkExport, BulkEdit, BulkRename, BulkDelete)
@register_model_view(ObjectPermission) @register_model_view(ObjectPermission)
@ -207,6 +221,11 @@ class ObjectPermissionBulkEditView(generic.BulkEditView):
form = forms.ObjectPermissionBulkEditForm form = forms.ObjectPermissionBulkEditForm
@register_model_view(ObjectPermission, 'bulk_rename', path='rename', detail=False)
class ObjectPermissionBulkRenameView(generic.BulkRenameView):
queryset = ObjectPermission.objects.all()
@register_model_view(ObjectPermission, 'bulk_delete', path='delete', detail=False) @register_model_view(ObjectPermission, 'bulk_delete', path='delete', detail=False)
class ObjectPermissionBulkDeleteView(generic.BulkDeleteView): class ObjectPermissionBulkDeleteView(generic.BulkDeleteView):
queryset = ObjectPermission.objects.all() queryset = ObjectPermission.objects.all()

View File

@ -1,3 +1,5 @@
<button type="submit" name="_rename" {% formaction %}="{{ url }}" class="btn btn-yellow"> {% if url %}
<i class="mdi mdi-pencil" aria-hidden="true"></i> {{ label }} <button type="submit" name="_rename" {% formaction %}="{{ url }}" class="btn btn-yellow">
</button> <i class="mdi mdi-pencil" aria-hidden="true"></i> {{ label }}
</button>
{% endif %}

View File

@ -22,6 +22,7 @@ __all__ = (
'content_type', 'content_type',
'content_type_id', 'content_type_id',
'fgcolor', 'fgcolor',
'getattr_',
'isodate', 'isodate',
'isodatetime', 'isodatetime',
'isotime', 'isotime',
@ -88,6 +89,14 @@ def fgcolor(value, dark='000000', light='ffffff'):
return f'#{foreground_color(value, dark, light)}' return f'#{foreground_color(value, dark, light)}'
@register.filter('getattr')
def getattr_(instance, name):
"""
Call getattr() on the object for the specified attribute.
"""
return getattr(instance, name, None)
@register.filter() @register.filter()
def meta(model, attr): def meta(model, attr):
""" """

View File

@ -13,7 +13,9 @@ from dcim.tables import DeviceTable
from extras.views import ObjectConfigContextView, ObjectRenderConfigView from extras.views import ObjectConfigContextView, ObjectRenderConfigView
from ipam.models import IPAddress, VLANGroup from ipam.models import IPAddress, VLANGroup
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
from netbox.object_actions import * from netbox.object_actions import (
AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport, BulkRename, DeleteObject, EditObject,
)
from netbox.views import generic from netbox.views import generic
from utilities.query import count_related from utilities.query import count_related
from utilities.query_functions import CollateAsChar from utilities.query_functions import CollateAsChar
@ -75,6 +77,11 @@ class ClusterTypeBulkEditView(generic.BulkEditView):
form = forms.ClusterTypeBulkEditForm form = forms.ClusterTypeBulkEditForm
@register_model_view(ClusterType, 'bulk_rename', path='rename', detail=False)
class ClusterTypeBulkRenameView(generic.BulkRenameView):
queryset = ClusterType.objects.all()
@register_model_view(ClusterType, 'bulk_delete', path='delete', detail=False) @register_model_view(ClusterType, 'bulk_delete', path='delete', detail=False)
class ClusterTypeBulkDeleteView(generic.BulkDeleteView): class ClusterTypeBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterType.objects.annotate( queryset = ClusterType.objects.annotate(
@ -148,6 +155,11 @@ class ClusterGroupBulkEditView(generic.BulkEditView):
form = forms.ClusterGroupBulkEditForm form = forms.ClusterGroupBulkEditForm
@register_model_view(ClusterGroup, 'bulk_rename', path='rename', detail=False)
class ClusterGroupBulkRenameView(generic.BulkRenameView):
queryset = ClusterGroup.objects.all()
@register_model_view(ClusterGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(ClusterGroup, 'bulk_delete', path='delete', detail=False)
class ClusterGroupBulkDeleteView(generic.BulkDeleteView): class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterGroup.objects.annotate( queryset = ClusterGroup.objects.annotate(
@ -262,6 +274,11 @@ class ClusterBulkEditView(generic.BulkEditView):
form = forms.ClusterBulkEditForm form = forms.ClusterBulkEditForm
@register_model_view(Cluster, 'bulk_rename', path='rename', detail=False)
class ClusterBulkRenameView(generic.BulkRenameView):
queryset = Cluster.objects.all()
@register_model_view(Cluster, 'bulk_delete', path='delete', detail=False) @register_model_view(Cluster, 'bulk_delete', path='delete', detail=False)
class ClusterBulkDeleteView(generic.BulkDeleteView): class ClusterBulkDeleteView(generic.BulkDeleteView):
queryset = Cluster.objects.all() queryset = Cluster.objects.all()
@ -322,7 +339,7 @@ class VirtualMachineListView(generic.ObjectListView):
filterset = filtersets.VirtualMachineFilterSet filterset = filtersets.VirtualMachineFilterSet
filterset_form = forms.VirtualMachineFilterForm filterset_form = forms.VirtualMachineFilterForm
table = tables.VirtualMachineTable table = tables.VirtualMachineTable
actions = (AddObject, BulkImport, BulkExport, BulkAddComponents, BulkEdit, BulkDelete) actions = (AddObject, BulkImport, BulkExport, BulkAddComponents, BulkEdit, BulkRename, BulkDelete)
@register_model_view(VirtualMachine) @register_model_view(VirtualMachine)
@ -417,6 +434,11 @@ class VirtualMachineBulkEditView(generic.BulkEditView):
form = forms.VirtualMachineBulkEditForm form = forms.VirtualMachineBulkEditForm
@register_model_view(VirtualMachine, 'bulk_rename', path='rename', detail=False)
class VirtualMachineBulkRenameView(generic.BulkRenameView):
queryset = VirtualMachine.objects.all()
@register_model_view(VirtualMachine, 'bulk_delete', path='delete', detail=False) @register_model_view(VirtualMachine, 'bulk_delete', path='delete', detail=False)
class VirtualMachineBulkDeleteView(generic.BulkDeleteView): class VirtualMachineBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualMachine.objects.prefetch_related('primary_ip4', 'primary_ip6') queryset = VirtualMachine.objects.prefetch_related('primary_ip4', 'primary_ip6')

View File

@ -1,4 +1,5 @@
from ipam.tables import RouteTargetTable from ipam.tables import RouteTargetTable
from netbox.object_actions import AddObject, BulkDelete, BulkEdit, BulkExport, BulkImport
from netbox.views import generic from netbox.views import generic
from utilities.query import count_related from utilities.query import count_related
from utilities.views import GetRelatedModelsMixin, register_model_view from utilities.views import GetRelatedModelsMixin, register_model_view
@ -58,6 +59,11 @@ class TunnelGroupBulkEditView(generic.BulkEditView):
form = forms.TunnelGroupBulkEditForm form = forms.TunnelGroupBulkEditForm
@register_model_view(TunnelGroup, 'bulk_rename', path='rename', detail=False)
class TunnelGroupBulkRenameView(generic.BulkRenameView):
queryset = TunnelGroup.objects.all()
@register_model_view(TunnelGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(TunnelGroup, 'bulk_delete', path='delete', detail=False)
class TunnelGroupBulkDeleteView(generic.BulkDeleteView): class TunnelGroupBulkDeleteView(generic.BulkDeleteView):
queryset = TunnelGroup.objects.annotate( queryset = TunnelGroup.objects.annotate(
@ -122,6 +128,11 @@ class TunnelBulkEditView(generic.BulkEditView):
form = forms.TunnelBulkEditForm form = forms.TunnelBulkEditForm
@register_model_view(Tunnel, 'bulk_rename', path='rename', detail=False)
class TunnelBulkRenameView(generic.BulkRenameView):
queryset = Tunnel.objects.all()
@register_model_view(Tunnel, 'bulk_delete', path='delete', detail=False) @register_model_view(Tunnel, 'bulk_delete', path='delete', detail=False)
class TunnelBulkDeleteView(generic.BulkDeleteView): class TunnelBulkDeleteView(generic.BulkDeleteView):
queryset = Tunnel.objects.annotate( queryset = Tunnel.objects.annotate(
@ -224,6 +235,11 @@ class IKEProposalBulkEditView(generic.BulkEditView):
form = forms.IKEProposalBulkEditForm form = forms.IKEProposalBulkEditForm
@register_model_view(IKEProposal, 'bulk_rename', path='rename', detail=False)
class IKEProposalBulkRenameView(generic.BulkRenameView):
queryset = IKEProposal.objects.all()
@register_model_view(IKEProposal, 'bulk_delete', path='delete', detail=False) @register_model_view(IKEProposal, 'bulk_delete', path='delete', detail=False)
class IKEProposalBulkDeleteView(generic.BulkDeleteView): class IKEProposalBulkDeleteView(generic.BulkDeleteView):
queryset = IKEProposal.objects.all() queryset = IKEProposal.objects.all()
@ -274,6 +290,11 @@ class IKEPolicyBulkEditView(generic.BulkEditView):
form = forms.IKEPolicyBulkEditForm form = forms.IKEPolicyBulkEditForm
@register_model_view(IKEPolicy, 'bulk_rename', path='rename', detail=False)
class IKEPolicyBulkRenameView(generic.BulkRenameView):
queryset = IKEPolicy.objects.all()
@register_model_view(IKEPolicy, 'bulk_delete', path='delete', detail=False) @register_model_view(IKEPolicy, 'bulk_delete', path='delete', detail=False)
class IKEPolicyBulkDeleteView(generic.BulkDeleteView): class IKEPolicyBulkDeleteView(generic.BulkDeleteView):
queryset = IKEPolicy.objects.all() queryset = IKEPolicy.objects.all()
@ -324,6 +345,11 @@ class IPSecProposalBulkEditView(generic.BulkEditView):
form = forms.IPSecProposalBulkEditForm form = forms.IPSecProposalBulkEditForm
@register_model_view(IPSecProposal, 'bulk_rename', path='rename', detail=False)
class IPSecProposalBulkRenameView(generic.BulkRenameView):
queryset = IPSecProposal.objects.all()
@register_model_view(IPSecProposal, 'bulk_delete', path='delete', detail=False) @register_model_view(IPSecProposal, 'bulk_delete', path='delete', detail=False)
class IPSecProposalBulkDeleteView(generic.BulkDeleteView): class IPSecProposalBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecProposal.objects.all() queryset = IPSecProposal.objects.all()
@ -374,6 +400,11 @@ class IPSecPolicyBulkEditView(generic.BulkEditView):
form = forms.IPSecPolicyBulkEditForm form = forms.IPSecPolicyBulkEditForm
@register_model_view(IPSecPolicy, 'bulk_rename', path='rename', detail=False)
class IPSecPolicyBulkRenameView(generic.BulkRenameView):
queryset = IPSecPolicy.objects.all()
@register_model_view(IPSecPolicy, 'bulk_delete', path='delete', detail=False) @register_model_view(IPSecPolicy, 'bulk_delete', path='delete', detail=False)
class IPSecPolicyBulkDeleteView(generic.BulkDeleteView): class IPSecPolicyBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecPolicy.objects.all() queryset = IPSecPolicy.objects.all()
@ -424,6 +455,11 @@ class IPSecProfileBulkEditView(generic.BulkEditView):
form = forms.IPSecProfileBulkEditForm form = forms.IPSecProfileBulkEditForm
@register_model_view(IPSecProfile, 'bulk_rename', path='rename', detail=False)
class IPSecProfileBulkRenameView(generic.BulkRenameView):
queryset = IPSecProfile.objects.all()
@register_model_view(IPSecProfile, 'bulk_delete', path='delete', detail=False) @register_model_view(IPSecProfile, 'bulk_delete', path='delete', detail=False)
class IPSecProfileBulkDeleteView(generic.BulkDeleteView): class IPSecProfileBulkDeleteView(generic.BulkDeleteView):
queryset = IPSecProfile.objects.all() queryset = IPSecProfile.objects.all()
@ -491,6 +527,11 @@ class L2VPNBulkEditView(generic.BulkEditView):
form = forms.L2VPNBulkEditForm form = forms.L2VPNBulkEditForm
@register_model_view(L2VPN, 'bulk_rename', path='rename', detail=False)
class L2VPNBulkRenameView(generic.BulkRenameView):
queryset = L2VPN.objects.all()
@register_model_view(L2VPN, 'bulk_delete', path='delete', detail=False) @register_model_view(L2VPN, 'bulk_delete', path='delete', detail=False)
class L2VPNBulkDeleteView(generic.BulkDeleteView): class L2VPNBulkDeleteView(generic.BulkDeleteView):
queryset = L2VPN.objects.all() queryset = L2VPN.objects.all()
@ -508,6 +549,7 @@ class L2VPNTerminationListView(generic.ObjectListView):
table = tables.L2VPNTerminationTable table = tables.L2VPNTerminationTable
filterset = filtersets.L2VPNTerminationFilterSet filterset = filtersets.L2VPNTerminationFilterSet
filterset_form = forms.L2VPNTerminationFilterForm filterset_form = forms.L2VPNTerminationFilterForm
actions = (AddObject, BulkImport, BulkExport, BulkEdit, BulkDelete)
@register_model_view(L2VPNTermination) @register_model_view(L2VPNTermination)

View File

@ -68,6 +68,11 @@ class WirelessLANGroupBulkEditView(generic.BulkEditView):
form = forms.WirelessLANGroupBulkEditForm form = forms.WirelessLANGroupBulkEditForm
@register_model_view(WirelessLANGroup, 'bulk_rename', path='rename', detail=False)
class WirelessLANGroupBulkRenameView(generic.BulkRenameView):
queryset = WirelessLANGroup.objects.all()
@register_model_view(WirelessLANGroup, 'bulk_delete', path='delete', detail=False) @register_model_view(WirelessLANGroup, 'bulk_delete', path='delete', detail=False)
class WirelessLANGroupBulkDeleteView(generic.BulkDeleteView): class WirelessLANGroupBulkDeleteView(generic.BulkDeleteView):
queryset = WirelessLANGroup.objects.add_related_count( queryset = WirelessLANGroup.objects.add_related_count(
@ -137,6 +142,12 @@ class WirelessLANBulkEditView(generic.BulkEditView):
form = forms.WirelessLANBulkEditForm form = forms.WirelessLANBulkEditForm
@register_model_view(WirelessLAN, 'bulk_rename', path='rename', detail=False)
class WirelessLANBulkRenameView(generic.BulkRenameView):
queryset = WirelessLAN.objects.all()
field_name = 'ssid'
@register_model_view(WirelessLAN, 'bulk_delete', path='delete', detail=False) @register_model_view(WirelessLAN, 'bulk_delete', path='delete', detail=False)
class WirelessLANBulkDeleteView(generic.BulkDeleteView): class WirelessLANBulkDeleteView(generic.BulkDeleteView):
queryset = WirelessLAN.objects.all() queryset = WirelessLAN.objects.all()
@ -187,6 +198,12 @@ class WirelessLinkBulkEditView(generic.BulkEditView):
form = forms.WirelessLinkBulkEditForm form = forms.WirelessLinkBulkEditForm
@register_model_view(WirelessLink, 'bulk_rename', path='rename', detail=False)
class WirelessLinkBulkRenameView(generic.BulkRenameView):
queryset = WirelessLink.objects.all()
field_name = 'ssid'
@register_model_view(WirelessLink, 'bulk_delete', path='delete', detail=False) @register_model_view(WirelessLink, 'bulk_delete', path='delete', detail=False)
class WirelessLinkBulkDeleteView(generic.BulkDeleteView): class WirelessLinkBulkDeleteView(generic.BulkDeleteView):
queryset = WirelessLink.objects.all() queryset = WirelessLink.objects.all()