diff --git a/netbox/circuits/urls.py b/netbox/circuits/urls.py index 55ceeddc3..d8c5ea276 100644 --- a/netbox/circuits/urls.py +++ b/netbox/circuits/urls.py @@ -1,9 +1,7 @@ from django.urls import include, path -from dcim.views import PathTraceView from utilities.urls import get_model_urls from . import views -from .models import CircuitTermination app_name = 'circuits' urlpatterns = [ @@ -14,9 +12,6 @@ urlpatterns = [ path('providers/import/', views.ProviderBulkImportView.as_view(), name='provider_import'), path('providers/edit/', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'), path('providers/delete/', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'), - path('providers//', views.ProviderView.as_view(), name='provider'), - path('providers//edit/', views.ProviderEditView.as_view(), name='provider_edit'), - path('providers//delete/', views.ProviderDeleteView.as_view(), name='provider_delete'), path('providers//', include(get_model_urls('circuits', 'provider'))), # Provider networks @@ -25,9 +20,6 @@ urlpatterns = [ path('provider-networks/import/', views.ProviderNetworkBulkImportView.as_view(), name='providernetwork_import'), path('provider-networks/edit/', views.ProviderNetworkBulkEditView.as_view(), name='providernetwork_bulk_edit'), path('provider-networks/delete/', views.ProviderNetworkBulkDeleteView.as_view(), name='providernetwork_bulk_delete'), - path('provider-networks//', views.ProviderNetworkView.as_view(), name='providernetwork'), - path('provider-networks//edit/', views.ProviderNetworkEditView.as_view(), name='providernetwork_edit'), - path('provider-networks//delete/', views.ProviderNetworkDeleteView.as_view(), name='providernetwork_delete'), path('provider-networks//', include(get_model_urls('circuits', 'providernetwork'))), # Circuit types @@ -36,9 +28,6 @@ urlpatterns = [ path('circuit-types/import/', views.CircuitTypeBulkImportView.as_view(), name='circuittype_import'), path('circuit-types/edit/', views.CircuitTypeBulkEditView.as_view(), name='circuittype_bulk_edit'), path('circuit-types/delete/', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'), - path('circuit-types//', views.CircuitTypeView.as_view(), name='circuittype'), - path('circuit-types//edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'), - path('circuit-types//delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'), path('circuit-types//', include(get_model_urls('circuits', 'circuittype'))), # Circuits @@ -47,16 +36,11 @@ urlpatterns = [ path('circuits/import/', views.CircuitBulkImportView.as_view(), name='circuit_import'), path('circuits/edit/', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'), path('circuits/delete/', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'), - path('circuits//', views.CircuitView.as_view(), name='circuit'), - path('circuits//edit/', views.CircuitEditView.as_view(), name='circuit_edit'), - path('circuits//delete/', views.CircuitDeleteView.as_view(), name='circuit_delete'), path('circuits//terminations/swap/', views.CircuitSwapTerminations.as_view(), name='circuit_terminations_swap'), path('circuits//', include(get_model_urls('circuits', 'circuit'))), # Circuit terminations path('circuit-terminations/add/', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'), - path('circuit-terminations//edit/', views.CircuitTerminationEditView.as_view(), name='circuittermination_edit'), - path('circuit-terminations//delete/', views.CircuitTerminationDeleteView.as_view(), name='circuittermination_delete'), - path('circuit-terminations//trace/', PathTraceView.as_view(), name='circuittermination_trace', kwargs={'model': CircuitTermination}), + path('circuit-terminations//', include(get_model_urls('circuits', 'circuittermination'))), ] diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 423bd67d6..dc809666b 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -3,9 +3,11 @@ from django.db import transaction from django.db.models import Q from django.shortcuts import get_object_or_404, redirect, render +from dcim.views import PathTraceView from netbox.views import generic from utilities.forms import ConfirmationForm from utilities.utils import count_related +from utilities.views import register_model_view from . import filtersets, forms, tables from .models import * @@ -23,6 +25,7 @@ class ProviderListView(generic.ObjectListView): table = tables.ProviderTable +@register_model_view(Provider) class ProviderView(generic.ObjectView): queryset = Provider.objects.all() @@ -41,11 +44,13 @@ class ProviderView(generic.ObjectView): } +@register_model_view(Provider, 'edit') class ProviderEditView(generic.ObjectEditView): queryset = Provider.objects.all() form = forms.ProviderForm +@register_model_view(Provider, 'delete') class ProviderDeleteView(generic.ObjectDeleteView): queryset = Provider.objects.all() @@ -84,6 +89,7 @@ class ProviderNetworkListView(generic.ObjectListView): table = tables.ProviderNetworkTable +@register_model_view(ProviderNetwork) class ProviderNetworkView(generic.ObjectView): queryset = ProviderNetwork.objects.all() @@ -103,11 +109,13 @@ class ProviderNetworkView(generic.ObjectView): } +@register_model_view(ProviderNetwork, 'edit') class ProviderNetworkEditView(generic.ObjectEditView): queryset = ProviderNetwork.objects.all() form = forms.ProviderNetworkForm +@register_model_view(ProviderNetwork, 'delete') class ProviderNetworkDeleteView(generic.ObjectDeleteView): queryset = ProviderNetwork.objects.all() @@ -144,6 +152,7 @@ class CircuitTypeListView(generic.ObjectListView): table = tables.CircuitTypeTable +@register_model_view(CircuitType) class CircuitTypeView(generic.ObjectView): queryset = CircuitType.objects.all() @@ -157,11 +166,13 @@ class CircuitTypeView(generic.ObjectView): } +@register_model_view(CircuitType, 'edit') class CircuitTypeEditView(generic.ObjectEditView): queryset = CircuitType.objects.all() form = forms.CircuitTypeForm +@register_model_view(CircuitType, 'delete') class CircuitTypeDeleteView(generic.ObjectDeleteView): queryset = CircuitType.objects.all() @@ -202,15 +213,18 @@ class CircuitListView(generic.ObjectListView): table = tables.CircuitTable +@register_model_view(Circuit) class CircuitView(generic.ObjectView): queryset = Circuit.objects.all() +@register_model_view(Circuit, 'edit') class CircuitEditView(generic.ObjectEditView): queryset = Circuit.objects.all() form = forms.CircuitForm +@register_model_view(Circuit, 'delete') class CircuitDeleteView(generic.ObjectDeleteView): queryset = Circuit.objects.all() @@ -318,11 +332,17 @@ class CircuitSwapTerminations(generic.ObjectEditView): # Circuit terminations # +@register_model_view(CircuitTermination, 'edit') class CircuitTerminationEditView(generic.ObjectEditView): queryset = CircuitTermination.objects.all() form = forms.CircuitTerminationForm template_name = 'circuits/circuittermination_edit.html' +@register_model_view(CircuitTermination, 'delete') class CircuitTerminationDeleteView(generic.ObjectDeleteView): queryset = CircuitTermination.objects.all() + + +# Trace view +register_model_view(CircuitTermination, 'trace', kwargs={'model': CircuitTermination})(PathTraceView) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 94c2a7131..ecd2d46c5 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -2,9 +2,6 @@ from django.urls import include, path from utilities.urls import get_model_urls from . import views -from .models import ( - ConsolePort, ConsoleServerPort, FrontPort, Interface, PowerFeed, PowerPort, PowerOutlet, RearPort, -) app_name = 'dcim' urlpatterns = [ @@ -15,9 +12,6 @@ urlpatterns = [ path('regions/import/', views.RegionBulkImportView.as_view(), name='region_import'), path('regions/edit/', views.RegionBulkEditView.as_view(), name='region_bulk_edit'), path('regions/delete/', views.RegionBulkDeleteView.as_view(), name='region_bulk_delete'), - path('regions//', views.RegionView.as_view(), name='region'), - path('regions//edit/', views.RegionEditView.as_view(), name='region_edit'), - path('regions//delete/', views.RegionDeleteView.as_view(), name='region_delete'), path('regions//', include(get_model_urls('dcim', 'region'))), # Site groups @@ -26,9 +20,6 @@ urlpatterns = [ path('site-groups/import/', views.SiteGroupBulkImportView.as_view(), name='sitegroup_import'), path('site-groups/edit/', views.SiteGroupBulkEditView.as_view(), name='sitegroup_bulk_edit'), path('site-groups/delete/', views.SiteGroupBulkDeleteView.as_view(), name='sitegroup_bulk_delete'), - path('site-groups//', views.SiteGroupView.as_view(), name='sitegroup'), - path('site-groups//edit/', views.SiteGroupEditView.as_view(), name='sitegroup_edit'), - path('site-groups//delete/', views.SiteGroupDeleteView.as_view(), name='sitegroup_delete'), path('site-groups//', include(get_model_urls('dcim', 'sitegroup'))), # Sites @@ -37,9 +28,6 @@ urlpatterns = [ path('sites/import/', views.SiteBulkImportView.as_view(), name='site_import'), path('sites/edit/', views.SiteBulkEditView.as_view(), name='site_bulk_edit'), path('sites/delete/', views.SiteBulkDeleteView.as_view(), name='site_bulk_delete'), - path('sites//', views.SiteView.as_view(), name='site'), - path('sites//edit/', views.SiteEditView.as_view(), name='site_edit'), - path('sites//delete/', views.SiteDeleteView.as_view(), name='site_delete'), path('sites//', include(get_model_urls('dcim', 'site'))), # Locations @@ -48,9 +36,6 @@ urlpatterns = [ path('locations/import/', views.LocationBulkImportView.as_view(), name='location_import'), path('locations/edit/', views.LocationBulkEditView.as_view(), name='location_bulk_edit'), path('locations/delete/', views.LocationBulkDeleteView.as_view(), name='location_bulk_delete'), - path('locations//', views.LocationView.as_view(), name='location'), - path('locations//edit/', views.LocationEditView.as_view(), name='location_edit'), - path('locations//delete/', views.LocationDeleteView.as_view(), name='location_delete'), path('locations//', include(get_model_urls('dcim', 'location'))), # Rack roles @@ -59,9 +44,6 @@ urlpatterns = [ path('rack-roles/import/', views.RackRoleBulkImportView.as_view(), name='rackrole_import'), path('rack-roles/edit/', views.RackRoleBulkEditView.as_view(), name='rackrole_bulk_edit'), path('rack-roles/delete/', views.RackRoleBulkDeleteView.as_view(), name='rackrole_bulk_delete'), - path('rack-roles//', views.RackRoleView.as_view(), name='rackrole'), - path('rack-roles//edit/', views.RackRoleEditView.as_view(), name='rackrole_edit'), - path('rack-roles//delete/', views.RackRoleDeleteView.as_view(), name='rackrole_delete'), path('rack-roles//', include(get_model_urls('dcim', 'rackrole'))), # Rack reservations @@ -70,9 +52,6 @@ urlpatterns = [ path('rack-reservations/import/', views.RackReservationImportView.as_view(), name='rackreservation_import'), path('rack-reservations/edit/', views.RackReservationBulkEditView.as_view(), name='rackreservation_bulk_edit'), path('rack-reservations/delete/', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'), - path('rack-reservations//', views.RackReservationView.as_view(), name='rackreservation'), - path('rack-reservations//edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'), - path('rack-reservations//delete/', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'), path('rack-reservations//', include(get_model_urls('dcim', 'rackreservation'))), # Racks @@ -82,9 +61,6 @@ urlpatterns = [ path('racks/import/', views.RackBulkImportView.as_view(), name='rack_import'), path('racks/edit/', views.RackBulkEditView.as_view(), name='rack_bulk_edit'), path('racks/delete/', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'), - path('racks//', views.RackView.as_view(), name='rack'), - path('racks//edit/', views.RackEditView.as_view(), name='rack_edit'), - path('racks//delete/', views.RackDeleteView.as_view(), name='rack_delete'), path('racks//', include(get_model_urls('dcim', 'rack'))), # Manufacturers @@ -93,9 +69,6 @@ urlpatterns = [ path('manufacturers/import/', views.ManufacturerBulkImportView.as_view(), name='manufacturer_import'), path('manufacturers/edit/', views.ManufacturerBulkEditView.as_view(), name='manufacturer_bulk_edit'), path('manufacturers/delete/', views.ManufacturerBulkDeleteView.as_view(), name='manufacturer_bulk_delete'), - path('manufacturers//', views.ManufacturerView.as_view(), name='manufacturer'), - path('manufacturers//edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'), - path('manufacturers//delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'), path('manufacturers//', include(get_model_urls('dcim', 'manufacturer'))), # Device types @@ -104,9 +77,6 @@ urlpatterns = [ path('device-types/import/', views.DeviceTypeImportView.as_view(), name='devicetype_import'), path('device-types/edit/', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'), path('device-types/delete/', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'), - path('device-types//', views.DeviceTypeView.as_view(), name='devicetype'), - path('device-types//edit/', views.DeviceTypeEditView.as_view(), name='devicetype_edit'), - path('device-types//delete/', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'), path('device-types//', include(get_model_urls('dcim', 'devicetype'))), # Module types @@ -115,9 +85,6 @@ urlpatterns = [ path('module-types/import/', views.ModuleTypeImportView.as_view(), name='moduletype_import'), path('module-types/edit/', views.ModuleTypeBulkEditView.as_view(), name='moduletype_bulk_edit'), path('module-types/delete/', views.ModuleTypeBulkDeleteView.as_view(), name='moduletype_bulk_delete'), - path('module-types//', views.ModuleTypeView.as_view(), name='moduletype'), - path('module-types//edit/', views.ModuleTypeEditView.as_view(), name='moduletype_edit'), - path('module-types//delete/', views.ModuleTypeDeleteView.as_view(), name='moduletype_delete'), path('module-types//', include(get_model_urls('dcim', 'moduletype'))), # Console port templates @@ -125,80 +92,70 @@ urlpatterns = [ path('console-port-templates/edit/', views.ConsolePortTemplateBulkEditView.as_view(), name='consoleporttemplate_bulk_edit'), path('console-port-templates/rename/', views.ConsolePortTemplateBulkRenameView.as_view(), name='consoleporttemplate_bulk_rename'), path('console-port-templates/delete/', views.ConsolePortTemplateBulkDeleteView.as_view(), name='consoleporttemplate_bulk_delete'), - path('console-port-templates//edit/', views.ConsolePortTemplateEditView.as_view(), name='consoleporttemplate_edit'), - path('console-port-templates//delete/', views.ConsolePortTemplateDeleteView.as_view(), name='consoleporttemplate_delete'), + path('console-port-templates//', include(get_model_urls('dcim', 'consoleporttemplate'))), # Console server port templates path('console-server-port-templates/add/', views.ConsoleServerPortTemplateCreateView.as_view(), name='consoleserverporttemplate_add'), path('console-server-port-templates/edit/', views.ConsoleServerPortTemplateBulkEditView.as_view(), name='consoleserverporttemplate_bulk_edit'), path('console-server-port-templates/rename/', views.ConsoleServerPortTemplateBulkRenameView.as_view(), name='consoleserverporttemplate_bulk_rename'), path('console-server-port-templates/delete/', views.ConsoleServerPortTemplateBulkDeleteView.as_view(), name='consoleserverporttemplate_bulk_delete'), - path('console-server-port-templates//edit/', views.ConsoleServerPortTemplateEditView.as_view(), name='consoleserverporttemplate_edit'), - path('console-server-port-templates//delete/', views.ConsoleServerPortTemplateDeleteView.as_view(), name='consoleserverporttemplate_delete'), + path('console-server-port-templates//', include(get_model_urls('dcim', 'consoleserverporttemplate'))), # Power port templates path('power-port-templates/add/', views.PowerPortTemplateCreateView.as_view(), name='powerporttemplate_add'), path('power-port-templates/edit/', views.PowerPortTemplateBulkEditView.as_view(), name='powerporttemplate_bulk_edit'), path('power-port-templates/rename/', views.PowerPortTemplateBulkRenameView.as_view(), name='powerporttemplate_bulk_rename'), path('power-port-templates/delete/', views.PowerPortTemplateBulkDeleteView.as_view(), name='powerporttemplate_bulk_delete'), - path('power-port-templates//edit/', views.PowerPortTemplateEditView.as_view(), name='powerporttemplate_edit'), - path('power-port-templates//delete/', views.PowerPortTemplateDeleteView.as_view(), name='powerporttemplate_delete'), + path('power-port-templates//', include(get_model_urls('dcim', 'powerporttemplate'))), # Power outlet templates path('power-outlet-templates/add/', views.PowerOutletTemplateCreateView.as_view(), name='poweroutlettemplate_add'), path('power-outlet-templates/edit/', views.PowerOutletTemplateBulkEditView.as_view(), name='poweroutlettemplate_bulk_edit'), path('power-outlet-templates/rename/', views.PowerOutletTemplateBulkRenameView.as_view(), name='poweroutlettemplate_bulk_rename'), path('power-outlet-templates/delete/', views.PowerOutletTemplateBulkDeleteView.as_view(), name='poweroutlettemplate_bulk_delete'), - path('power-outlet-templates//edit/', views.PowerOutletTemplateEditView.as_view(), name='poweroutlettemplate_edit'), - path('power-outlet-templates//delete/', views.PowerOutletTemplateDeleteView.as_view(), name='poweroutlettemplate_delete'), + path('power-outlet-templates//', include(get_model_urls('dcim', 'poweroutlettemplate'))), # Interface templates path('interface-templates/add/', views.InterfaceTemplateCreateView.as_view(), name='interfacetemplate_add'), path('interface-templates/edit/', views.InterfaceTemplateBulkEditView.as_view(), name='interfacetemplate_bulk_edit'), path('interface-templates/rename/', views.InterfaceTemplateBulkRenameView.as_view(), name='interfacetemplate_bulk_rename'), path('interface-templates/delete/', views.InterfaceTemplateBulkDeleteView.as_view(), name='interfacetemplate_bulk_delete'), - path('interface-templates//edit/', views.InterfaceTemplateEditView.as_view(), name='interfacetemplate_edit'), - path('interface-templates//delete/', views.InterfaceTemplateDeleteView.as_view(), name='interfacetemplate_delete'), + path('interface-templates//', include(get_model_urls('dcim', 'interfacetemplate'))), # Front port templates path('front-port-templates/add/', views.FrontPortTemplateCreateView.as_view(), name='frontporttemplate_add'), path('front-port-templates/edit/', views.FrontPortTemplateBulkEditView.as_view(), name='frontporttemplate_bulk_edit'), path('front-port-templates/rename/', views.FrontPortTemplateBulkRenameView.as_view(), name='frontporttemplate_bulk_rename'), path('front-port-templates/delete/', views.FrontPortTemplateBulkDeleteView.as_view(), name='frontporttemplate_bulk_delete'), - path('front-port-templates//edit/', views.FrontPortTemplateEditView.as_view(), name='frontporttemplate_edit'), - path('front-port-templates//delete/', views.FrontPortTemplateDeleteView.as_view(), name='frontporttemplate_delete'), + path('front-port-templates//', include(get_model_urls('dcim', 'frontporttemplate'))), # Rear port templates path('rear-port-templates/add/', views.RearPortTemplateCreateView.as_view(), name='rearporttemplate_add'), path('rear-port-templates/edit/', views.RearPortTemplateBulkEditView.as_view(), name='rearporttemplate_bulk_edit'), path('rear-port-templates/rename/', views.RearPortTemplateBulkRenameView.as_view(), name='rearporttemplate_bulk_rename'), path('rear-port-templates/delete/', views.RearPortTemplateBulkDeleteView.as_view(), name='rearporttemplate_bulk_delete'), - path('rear-port-templates//edit/', views.RearPortTemplateEditView.as_view(), name='rearporttemplate_edit'), - path('rear-port-templates//delete/', views.RearPortTemplateDeleteView.as_view(), name='rearporttemplate_delete'), + path('rear-port-templates//', include(get_model_urls('dcim', 'rearporttemplate'))), # Device bay templates path('device-bay-templates/add/', views.DeviceBayTemplateCreateView.as_view(), name='devicebaytemplate_add'), path('device-bay-templates/edit/', views.DeviceBayTemplateBulkEditView.as_view(), name='devicebaytemplate_bulk_edit'), path('device-bay-templates/rename/', views.DeviceBayTemplateBulkRenameView.as_view(), name='devicebaytemplate_bulk_rename'), path('device-bay-templates/delete/', views.DeviceBayTemplateBulkDeleteView.as_view(), name='devicebaytemplate_bulk_delete'), - path('device-bay-templates//edit/', views.DeviceBayTemplateEditView.as_view(), name='devicebaytemplate_edit'), - path('device-bay-templates//delete/', views.DeviceBayTemplateDeleteView.as_view(), name='devicebaytemplate_delete'), + path('device-bay-templates//', include(get_model_urls('dcim', 'devicebaytemplate'))), # Module bay templates path('module-bay-templates/add/', views.ModuleBayTemplateCreateView.as_view(), name='modulebaytemplate_add'), path('module-bay-templates/edit/', views.ModuleBayTemplateBulkEditView.as_view(), name='modulebaytemplate_bulk_edit'), path('module-bay-templates/rename/', views.ModuleBayTemplateBulkRenameView.as_view(), name='modulebaytemplate_bulk_rename'), path('module-bay-templates/delete/', views.ModuleBayTemplateBulkDeleteView.as_view(), name='modulebaytemplate_bulk_delete'), - path('module-bay-templates//edit/', views.ModuleBayTemplateEditView.as_view(), name='modulebaytemplate_edit'), - path('module-bay-templates//delete/', views.ModuleBayTemplateDeleteView.as_view(), name='modulebaytemplate_delete'), + path('module-bay-templates//', include(get_model_urls('dcim', 'modulebaytemplate'))), # Inventory item templates path('inventory-item-templates/add/', views.InventoryItemTemplateCreateView.as_view(), name='inventoryitemtemplate_add'), path('inventory-item-templates/edit/', views.InventoryItemTemplateBulkEditView.as_view(), name='inventoryitemtemplate_bulk_edit'), path('inventory-item-templates/rename/', views.InventoryItemTemplateBulkRenameView.as_view(), name='inventoryitemtemplate_bulk_rename'), path('inventory-item-templates/delete/', views.InventoryItemTemplateBulkDeleteView.as_view(), name='inventoryitemtemplate_bulk_delete'), - path('inventory-item-templates//edit/', views.InventoryItemTemplateEditView.as_view(), name='inventoryitemtemplate_edit'), - path('inventory-item-templates//delete/', views.InventoryItemTemplateDeleteView.as_view(), name='inventoryitemtemplate_delete'), + path('inventory-item-templates//', include(get_model_urls('dcim', 'inventoryitemtemplate'))), # Device roles path('device-roles/', views.DeviceRoleListView.as_view(), name='devicerole_list'), @@ -206,9 +163,6 @@ urlpatterns = [ path('device-roles/import/', views.DeviceRoleBulkImportView.as_view(), name='devicerole_import'), path('device-roles/edit/', views.DeviceRoleBulkEditView.as_view(), name='devicerole_bulk_edit'), path('device-roles/delete/', views.DeviceRoleBulkDeleteView.as_view(), name='devicerole_bulk_delete'), - path('device-roles//', views.DeviceRoleView.as_view(), name='devicerole'), - path('device-roles//edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'), - path('device-roles//delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'), path('device-roles//', include(get_model_urls('dcim', 'devicerole'))), # Platforms @@ -217,9 +171,6 @@ urlpatterns = [ path('platforms/import/', views.PlatformBulkImportView.as_view(), name='platform_import'), path('platforms/edit/', views.PlatformBulkEditView.as_view(), name='platform_bulk_edit'), path('platforms/delete/', views.PlatformBulkDeleteView.as_view(), name='platform_bulk_delete'), - path('platforms//', views.PlatformView.as_view(), name='platform'), - path('platforms//edit/', views.PlatformEditView.as_view(), name='platform_edit'), - path('platforms//delete/', views.PlatformDeleteView.as_view(), name='platform_delete'), path('platforms//', include(get_model_urls('dcim', 'platform'))), # Devices @@ -230,9 +181,6 @@ urlpatterns = [ path('devices/edit/', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'), path('devices/rename/', views.DeviceBulkRenameView.as_view(), name='device_bulk_rename'), path('devices/delete/', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'), - path('devices//', views.DeviceView.as_view(), name='device'), - path('devices//edit/', views.DeviceEditView.as_view(), name='device_edit'), - path('devices//delete/', views.DeviceDeleteView.as_view(), name='device_delete'), path('devices//', include(get_model_urls('dcim', 'device'))), # Modules @@ -241,9 +189,6 @@ urlpatterns = [ path('modules/import/', views.ModuleBulkImportView.as_view(), name='module_import'), path('modules/edit/', views.ModuleBulkEditView.as_view(), name='module_bulk_edit'), path('modules/delete/', views.ModuleBulkDeleteView.as_view(), name='module_bulk_delete'), - path('modules//', views.ModuleView.as_view(), name='module'), - path('modules//edit/', views.ModuleEditView.as_view(), name='module_edit'), - path('modules//delete/', views.ModuleDeleteView.as_view(), name='module_delete'), path('modules//', include(get_model_urls('dcim', 'module'))), # Console ports @@ -254,10 +199,6 @@ urlpatterns = [ path('console-ports/rename/', views.ConsolePortBulkRenameView.as_view(), name='consoleport_bulk_rename'), path('console-ports/disconnect/', views.ConsolePortBulkDisconnectView.as_view(), name='consoleport_bulk_disconnect'), path('console-ports/delete/', views.ConsolePortBulkDeleteView.as_view(), name='consoleport_bulk_delete'), - path('console-ports//', views.ConsolePortView.as_view(), name='consoleport'), - path('console-ports//edit/', views.ConsolePortEditView.as_view(), name='consoleport_edit'), - path('console-ports//delete/', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'), - path('console-ports//trace/', views.PathTraceView.as_view(), name='consoleport_trace', kwargs={'model': ConsolePort}), path('console-ports//', include(get_model_urls('dcim', 'consoleport'))), path('devices/console-ports/add/', views.DeviceBulkAddConsolePortView.as_view(), name='device_bulk_add_consoleport'), @@ -269,10 +210,6 @@ urlpatterns = [ path('console-server-ports/rename/', views.ConsoleServerPortBulkRenameView.as_view(), name='consoleserverport_bulk_rename'), path('console-server-ports/disconnect/', views.ConsoleServerPortBulkDisconnectView.as_view(), name='consoleserverport_bulk_disconnect'), path('console-server-ports/delete/', views.ConsoleServerPortBulkDeleteView.as_view(), name='consoleserverport_bulk_delete'), - path('console-server-ports//', views.ConsoleServerPortView.as_view(), name='consoleserverport'), - path('console-server-ports//edit/', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'), - path('console-server-ports//delete/', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'), - path('console-server-ports//trace/', views.PathTraceView.as_view(), name='consoleserverport_trace', kwargs={'model': ConsoleServerPort}), path('console-server-ports//', include(get_model_urls('dcim', 'consoleserverport'))), path('devices/console-server-ports/add/', views.DeviceBulkAddConsoleServerPortView.as_view(), name='device_bulk_add_consoleserverport'), @@ -284,10 +221,6 @@ urlpatterns = [ path('power-ports/rename/', views.PowerPortBulkRenameView.as_view(), name='powerport_bulk_rename'), path('power-ports/disconnect/', views.PowerPortBulkDisconnectView.as_view(), name='powerport_bulk_disconnect'), path('power-ports/delete/', views.PowerPortBulkDeleteView.as_view(), name='powerport_bulk_delete'), - path('power-ports//', views.PowerPortView.as_view(), name='powerport'), - path('power-ports//edit/', views.PowerPortEditView.as_view(), name='powerport_edit'), - path('power-ports//delete/', views.PowerPortDeleteView.as_view(), name='powerport_delete'), - path('power-ports//trace/', views.PathTraceView.as_view(), name='powerport_trace', kwargs={'model': PowerPort}), path('power-ports//', include(get_model_urls('dcim', 'powerport'))), path('devices/power-ports/add/', views.DeviceBulkAddPowerPortView.as_view(), name='device_bulk_add_powerport'), @@ -299,10 +232,6 @@ urlpatterns = [ path('power-outlets/rename/', views.PowerOutletBulkRenameView.as_view(), name='poweroutlet_bulk_rename'), path('power-outlets/disconnect/', views.PowerOutletBulkDisconnectView.as_view(), name='poweroutlet_bulk_disconnect'), path('power-outlets/delete/', views.PowerOutletBulkDeleteView.as_view(), name='poweroutlet_bulk_delete'), - path('power-outlets//', views.PowerOutletView.as_view(), name='poweroutlet'), - path('power-outlets//edit/', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'), - path('power-outlets//delete/', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'), - path('power-outlets//trace/', views.PathTraceView.as_view(), name='poweroutlet_trace', kwargs={'model': PowerOutlet}), path('power-outlets//', include(get_model_urls('dcim', 'poweroutlet'))), path('devices/power-outlets/add/', views.DeviceBulkAddPowerOutletView.as_view(), name='device_bulk_add_poweroutlet'), @@ -314,10 +243,6 @@ urlpatterns = [ path('interfaces/rename/', views.InterfaceBulkRenameView.as_view(), name='interface_bulk_rename'), path('interfaces/disconnect/', views.InterfaceBulkDisconnectView.as_view(), name='interface_bulk_disconnect'), path('interfaces/delete/', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'), - path('interfaces//', views.InterfaceView.as_view(), name='interface'), - path('interfaces//edit/', views.InterfaceEditView.as_view(), name='interface_edit'), - path('interfaces//delete/', views.InterfaceDeleteView.as_view(), name='interface_delete'), - path('interfaces//trace/', views.PathTraceView.as_view(), name='interface_trace', kwargs={'model': Interface}), path('interfaces//', include(get_model_urls('dcim', 'interface'))), path('devices/interfaces/add/', views.DeviceBulkAddInterfaceView.as_view(), name='device_bulk_add_interface'), @@ -329,10 +254,6 @@ urlpatterns = [ path('front-ports/rename/', views.FrontPortBulkRenameView.as_view(), name='frontport_bulk_rename'), path('front-ports/disconnect/', views.FrontPortBulkDisconnectView.as_view(), name='frontport_bulk_disconnect'), path('front-ports/delete/', views.FrontPortBulkDeleteView.as_view(), name='frontport_bulk_delete'), - path('front-ports//', views.FrontPortView.as_view(), name='frontport'), - path('front-ports//edit/', views.FrontPortEditView.as_view(), name='frontport_edit'), - path('front-ports//delete/', views.FrontPortDeleteView.as_view(), name='frontport_delete'), - path('front-ports//trace/', views.PathTraceView.as_view(), name='frontport_trace', kwargs={'model': FrontPort}), path('front-ports//', include(get_model_urls('dcim', 'frontport'))), # path('devices/front-ports/add/', views.DeviceBulkAddFrontPortView.as_view(), name='device_bulk_add_frontport'), @@ -344,10 +265,6 @@ urlpatterns = [ path('rear-ports/rename/', views.RearPortBulkRenameView.as_view(), name='rearport_bulk_rename'), path('rear-ports/disconnect/', views.RearPortBulkDisconnectView.as_view(), name='rearport_bulk_disconnect'), path('rear-ports/delete/', views.RearPortBulkDeleteView.as_view(), name='rearport_bulk_delete'), - path('rear-ports//', views.RearPortView.as_view(), name='rearport'), - path('rear-ports//edit/', views.RearPortEditView.as_view(), name='rearport_edit'), - path('rear-ports//delete/', views.RearPortDeleteView.as_view(), name='rearport_delete'), - path('rear-ports//trace/', views.PathTraceView.as_view(), name='rearport_trace', kwargs={'model': RearPort}), path('rear-ports//', include(get_model_urls('dcim', 'rearport'))), path('devices/rear-ports/add/', views.DeviceBulkAddRearPortView.as_view(), name='device_bulk_add_rearport'), @@ -358,9 +275,6 @@ urlpatterns = [ path('module-bays/edit/', views.ModuleBayBulkEditView.as_view(), name='modulebay_bulk_edit'), path('module-bays/rename/', views.ModuleBayBulkRenameView.as_view(), name='modulebay_bulk_rename'), path('module-bays/delete/', views.ModuleBayBulkDeleteView.as_view(), name='modulebay_bulk_delete'), - path('module-bays//', views.ModuleBayView.as_view(), name='modulebay'), - path('module-bays//edit/', views.ModuleBayEditView.as_view(), name='modulebay_edit'), - path('module-bays//delete/', views.ModuleBayDeleteView.as_view(), name='modulebay_delete'), path('module-bays//', include(get_model_urls('dcim', 'modulebay'))), path('devices/module-bays/add/', views.DeviceBulkAddModuleBayView.as_view(), name='device_bulk_add_modulebay'), @@ -371,11 +285,6 @@ urlpatterns = [ path('device-bays/edit/', views.DeviceBayBulkEditView.as_view(), name='devicebay_bulk_edit'), path('device-bays/rename/', views.DeviceBayBulkRenameView.as_view(), name='devicebay_bulk_rename'), path('device-bays/delete/', views.DeviceBayBulkDeleteView.as_view(), name='devicebay_bulk_delete'), - path('device-bays//', views.DeviceBayView.as_view(), name='devicebay'), - path('device-bays//edit/', views.DeviceBayEditView.as_view(), name='devicebay_edit'), - path('device-bays//delete/', views.DeviceBayDeleteView.as_view(), name='devicebay_delete'), - path('device-bays//populate/', views.DeviceBayPopulateView.as_view(), name='devicebay_populate'), - path('device-bays//depopulate/', views.DeviceBayDepopulateView.as_view(), name='devicebay_depopulate'), path('device-bays//', include(get_model_urls('dcim', 'devicebay'))), path('devices/device-bays/add/', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'), @@ -386,9 +295,6 @@ urlpatterns = [ path('inventory-items/edit/', views.InventoryItemBulkEditView.as_view(), name='inventoryitem_bulk_edit'), path('inventory-items/rename/', views.InventoryItemBulkRenameView.as_view(), name='inventoryitem_bulk_rename'), path('inventory-items/delete/', views.InventoryItemBulkDeleteView.as_view(), name='inventoryitem_bulk_delete'), - path('inventory-items//', views.InventoryItemView.as_view(), name='inventoryitem'), - path('inventory-items//edit/', views.InventoryItemEditView.as_view(), name='inventoryitem_edit'), - path('inventory-items//delete/', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'), path('inventory-items//', include(get_model_urls('dcim', 'inventoryitem'))), path('devices/inventory-items/add/', views.DeviceBulkAddInventoryItemView.as_view(), name='device_bulk_add_inventoryitem'), @@ -398,9 +304,6 @@ urlpatterns = [ path('inventory-item-roles/import/', views.InventoryItemRoleBulkImportView.as_view(), name='inventoryitemrole_import'), path('inventory-item-roles/edit/', views.InventoryItemRoleBulkEditView.as_view(), name='inventoryitemrole_bulk_edit'), path('inventory-item-roles/delete/', views.InventoryItemRoleBulkDeleteView.as_view(), name='inventoryitemrole_bulk_delete'), - path('inventory-item-roles//', views.InventoryItemRoleView.as_view(), name='inventoryitemrole'), - path('inventory-item-roles//edit/', views.InventoryItemRoleEditView.as_view(), name='inventoryitemrole_edit'), - path('inventory-item-roles//delete/', views.InventoryItemRoleDeleteView.as_view(), name='inventoryitemrole_delete'), path('inventory-item-roles//', include(get_model_urls('dcim', 'inventoryitemrole'))), # Cables @@ -409,9 +312,6 @@ urlpatterns = [ path('cables/import/', views.CableBulkImportView.as_view(), name='cable_import'), path('cables/edit/', views.CableBulkEditView.as_view(), name='cable_bulk_edit'), path('cables/delete/', views.CableBulkDeleteView.as_view(), name='cable_bulk_delete'), - path('cables//', views.CableView.as_view(), name='cable'), - path('cables//edit/', views.CableEditView.as_view(), name='cable_edit'), - path('cables//delete/', views.CableDeleteView.as_view(), name='cable_delete'), path('cables//', include(get_model_urls('dcim', 'cable'))), # Console/power/interface connections (read-only) @@ -425,10 +325,6 @@ urlpatterns = [ path('virtual-chassis/import/', views.VirtualChassisBulkImportView.as_view(), name='virtualchassis_import'), path('virtual-chassis/edit/', views.VirtualChassisBulkEditView.as_view(), name='virtualchassis_bulk_edit'), path('virtual-chassis/delete/', views.VirtualChassisBulkDeleteView.as_view(), name='virtualchassis_bulk_delete'), - path('virtual-chassis//', views.VirtualChassisView.as_view(), name='virtualchassis'), - path('virtual-chassis//edit/', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'), - path('virtual-chassis//delete/', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'), - path('virtual-chassis//add-member/', views.VirtualChassisAddMemberView.as_view(), name='virtualchassis_add_member'), path('virtual-chassis//', include(get_model_urls('dcim', 'virtualchassis'))), path('virtual-chassis-members//delete/', views.VirtualChassisRemoveMemberView.as_view(), name='virtualchassis_remove_member'), @@ -438,9 +334,6 @@ urlpatterns = [ path('power-panels/import/', views.PowerPanelBulkImportView.as_view(), name='powerpanel_import'), path('power-panels/edit/', views.PowerPanelBulkEditView.as_view(), name='powerpanel_bulk_edit'), path('power-panels/delete/', views.PowerPanelBulkDeleteView.as_view(), name='powerpanel_bulk_delete'), - path('power-panels//', views.PowerPanelView.as_view(), name='powerpanel'), - path('power-panels//edit/', views.PowerPanelEditView.as_view(), name='powerpanel_edit'), - path('power-panels//delete/', views.PowerPanelDeleteView.as_view(), name='powerpanel_delete'), path('power-panels//', include(get_model_urls('dcim', 'powerpanel'))), # Power feeds @@ -450,10 +343,6 @@ urlpatterns = [ path('power-feeds/edit/', views.PowerFeedBulkEditView.as_view(), name='powerfeed_bulk_edit'), path('power-feeds/disconnect/', views.PowerFeedBulkDisconnectView.as_view(), name='powerfeed_bulk_disconnect'), path('power-feeds/delete/', views.PowerFeedBulkDeleteView.as_view(), name='powerfeed_bulk_delete'), - path('power-feeds//', views.PowerFeedView.as_view(), name='powerfeed'), - path('power-feeds//edit/', views.PowerFeedEditView.as_view(), name='powerfeed_edit'), - path('power-feeds//delete/', views.PowerFeedDeleteView.as_view(), name='powerfeed_delete'), - path('power-feeds//trace/', views.PathTraceView.as_view(), name='powerfeed_trace', kwargs={'model': PowerFeed}), path('power-feeds//', include(get_model_urls('dcim', 'powerfeed'))), ] diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ef0c1f917..195de2937 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -134,6 +134,61 @@ class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View) }) +class PathTraceView(generic.ObjectView): + """ + Trace a cable path beginning from the given path endpoint (origin). + """ + additional_permissions = ['dcim.view_cable'] + template_name = 'dcim/cable_trace.html' + + def dispatch(self, request, *args, **kwargs): + model = kwargs.pop('model') + self.queryset = model.objects.all() + + return super().dispatch(request, *args, **kwargs) + + def get_extra_context(self, request, instance): + related_paths = [] + + # If tracing a PathEndpoint, locate the CablePath (if one exists) by its origin + if isinstance(instance, PathEndpoint): + path = instance._path + + # Otherwise, find all CablePaths which traverse the specified object + else: + related_paths = CablePath.objects.filter(_nodes__contains=instance) + # Check for specification of a particular path (when tracing pass-through ports) + try: + path_id = int(request.GET.get('cablepath_id')) + except TypeError: + path_id = None + if path_id in list(related_paths.values_list('pk', flat=True)): + path = CablePath.objects.get(pk=path_id) + else: + path = related_paths.first() + + # No paths found + if path is None: + return { + 'path': None + } + + # Get the total length of the cable and whether the length is definitive (fully defined) + total_length, is_definitive = path.get_total_length() if path else (None, False) + + # Determine the path to the SVG trace image + api_viewname = f"{path.origin_type.app_label}-api:{path.origin_type.model}-trace" + svg_url = f"{reverse(api_viewname, kwargs={'pk': path.origins[0].pk})}?render=svg" + + return { + 'path': path, + 'related_paths': related_paths, + 'total_length': total_length, + 'is_definitive': is_definitive, + 'svg_url': svg_url, + } + + # # Regions # @@ -151,6 +206,7 @@ class RegionListView(generic.ObjectListView): table = tables.RegionTable +@register_model_view(Region) class RegionView(generic.ObjectView): queryset = Region.objects.all() @@ -179,11 +235,13 @@ class RegionView(generic.ObjectView): } +@register_model_view(Region, 'edit') class RegionEditView(generic.ObjectEditView): queryset = Region.objects.all() form = forms.RegionForm +@register_model_view(Region, 'delete') class RegionDeleteView(generic.ObjectDeleteView): queryset = Region.objects.all() @@ -236,6 +294,7 @@ class SiteGroupListView(generic.ObjectListView): table = tables.SiteGroupTable +@register_model_view(SiteGroup) class SiteGroupView(generic.ObjectView): queryset = SiteGroup.objects.all() @@ -264,11 +323,13 @@ class SiteGroupView(generic.ObjectView): } +@register_model_view(SiteGroup, 'edit') class SiteGroupEditView(generic.ObjectEditView): queryset = SiteGroup.objects.all() form = forms.SiteGroupForm +@register_model_view(SiteGroup, 'delete') class SiteGroupDeleteView(generic.ObjectDeleteView): queryset = SiteGroup.objects.all() @@ -315,6 +376,7 @@ class SiteListView(generic.ObjectListView): table = tables.SiteTable +@register_model_view(Site) class SiteView(generic.ObjectView): queryset = Site.objects.prefetch_related('tenant__group') @@ -367,11 +429,13 @@ class SiteView(generic.ObjectView): } +@register_model_view(Site, 'edit') class SiteEditView(generic.ObjectEditView): queryset = Site.objects.all() form = forms.SiteForm +@register_model_view(Site, 'delete') class SiteDeleteView(generic.ObjectDeleteView): queryset = Site.objects.all() @@ -418,6 +482,7 @@ class LocationListView(generic.ObjectListView): table = tables.LocationTable +@register_model_view(Location) class LocationView(generic.ObjectView): queryset = Location.objects.all() @@ -457,11 +522,13 @@ class LocationView(generic.ObjectView): } +@register_model_view(Location, 'edit') class LocationEditView(generic.ObjectEditView): queryset = Location.objects.all() form = forms.LocationForm +@register_model_view(Location, 'delete') class LocationDeleteView(generic.ObjectDeleteView): queryset = Location.objects.all() @@ -510,6 +577,7 @@ class RackRoleListView(generic.ObjectListView): table = tables.RackRoleTable +@register_model_view(RackRole) class RackRoleView(generic.ObjectView): queryset = RackRole.objects.all() @@ -528,11 +596,13 @@ class RackRoleView(generic.ObjectView): } +@register_model_view(RackRole, 'edit') class RackRoleEditView(generic.ObjectEditView): queryset = RackRole.objects.all() form = forms.RackRoleForm +@register_model_view(RackRole, 'delete') class RackRoleDeleteView(generic.ObjectDeleteView): queryset = RackRole.objects.all() @@ -623,6 +693,7 @@ class RackElevationListView(generic.ObjectListView): }) +@register_model_view(Rack) class RackView(generic.ObjectView): queryset = Rack.objects.prefetch_related('site__region', 'tenant__group', 'location', 'role') @@ -666,12 +737,14 @@ class RackView(generic.ObjectView): } +@register_model_view(Rack, 'edit') class RackEditView(generic.ObjectEditView): queryset = Rack.objects.all() form = forms.RackForm template_name = 'dcim/rack_edit.html' +@register_model_view(Rack, 'delete') class RackDeleteView(generic.ObjectDeleteView): queryset = Rack.objects.all() @@ -706,10 +779,12 @@ class RackReservationListView(generic.ObjectListView): table = tables.RackReservationTable +@register_model_view(RackReservation) class RackReservationView(generic.ObjectView): queryset = RackReservation.objects.all() +@register_model_view(RackReservation, 'edit') class RackReservationEditView(generic.ObjectEditView): queryset = RackReservation.objects.all() form = forms.RackReservationForm @@ -722,6 +797,7 @@ class RackReservationEditView(generic.ObjectEditView): return obj +@register_model_view(RackReservation, 'delete') class RackReservationDeleteView(generic.ObjectDeleteView): queryset = RackReservation.objects.all() @@ -770,6 +846,7 @@ class ManufacturerListView(generic.ObjectListView): table = tables.ManufacturerTable +@register_model_view(Manufacturer) class ManufacturerView(generic.ObjectView): queryset = Manufacturer.objects.all() @@ -796,11 +873,13 @@ class ManufacturerView(generic.ObjectView): } +@register_model_view(Manufacturer, 'edit') class ManufacturerEditView(generic.ObjectEditView): queryset = Manufacturer.objects.all() form = forms.ManufacturerForm +@register_model_view(Manufacturer, 'delete') class ManufacturerDeleteView(generic.ObjectDeleteView): queryset = Manufacturer.objects.all() @@ -840,6 +919,7 @@ class DeviceTypeListView(generic.ObjectListView): table = tables.DeviceTypeTable +@register_model_view(DeviceType) class DeviceTypeView(generic.ObjectView): queryset = DeviceType.objects.all() @@ -851,6 +931,17 @@ class DeviceTypeView(generic.ObjectView): } +@register_model_view(DeviceType, 'edit') +class DeviceTypeEditView(generic.ObjectEditView): + queryset = DeviceType.objects.all() + form = forms.DeviceTypeForm + + +@register_model_view(DeviceType, 'delete') +class DeviceTypeDeleteView(generic.ObjectDeleteView): + queryset = DeviceType.objects.all() + + @register_model_view(DeviceType, 'consoleports', path='console-ports') class DeviceTypeConsolePortsView(DeviceTypeComponentsView): child_model = ConsolePortTemplate @@ -981,15 +1072,6 @@ class DeviceTypeInventoryItemsView(DeviceTypeComponentsView): ) -class DeviceTypeEditView(generic.ObjectEditView): - queryset = DeviceType.objects.all() - form = forms.DeviceTypeForm - - -class DeviceTypeDeleteView(generic.ObjectDeleteView): - queryset = DeviceType.objects.all() - - class DeviceTypeImportView(generic.ObjectImportView): additional_permissions = [ 'dcim.add_devicetype', @@ -1054,6 +1136,7 @@ class ModuleTypeListView(generic.ObjectListView): table = tables.ModuleTypeTable +@register_model_view(ModuleType) class ModuleTypeView(generic.ObjectView): queryset = ModuleType.objects.all() @@ -1065,6 +1148,17 @@ class ModuleTypeView(generic.ObjectView): } +@register_model_view(ModuleType, 'edit') +class ModuleTypeEditView(generic.ObjectEditView): + queryset = ModuleType.objects.all() + form = forms.ModuleTypeForm + + +@register_model_view(ModuleType, 'delete') +class ModuleTypeDeleteView(generic.ObjectDeleteView): + queryset = ModuleType.objects.all() + + @register_model_view(ModuleType, 'consoleports', path='console-ports') class ModuleTypeConsolePortsView(ModuleTypeComponentsView): child_model = ConsolePortTemplate @@ -1156,15 +1250,6 @@ class ModuleTypeRearPortsView(ModuleTypeComponentsView): ) -class ModuleTypeEditView(generic.ObjectEditView): - queryset = ModuleType.objects.all() - form = forms.ModuleTypeForm - - -class ModuleTypeDeleteView(generic.ObjectDeleteView): - queryset = ModuleType.objects.all() - - class ModuleTypeImportView(generic.ObjectImportView): additional_permissions = [ 'dcim.add_moduletype', @@ -1220,11 +1305,13 @@ class ConsolePortTemplateCreateView(generic.ComponentCreateView): model_form = forms.ConsolePortTemplateForm +@register_model_view(ConsolePortTemplate, 'edit') class ConsolePortTemplateEditView(generic.ObjectEditView): queryset = ConsolePortTemplate.objects.all() form = forms.ConsolePortTemplateForm +@register_model_view(ConsolePortTemplate, 'delete') class ConsolePortTemplateDeleteView(generic.ObjectDeleteView): queryset = ConsolePortTemplate.objects.all() @@ -1254,11 +1341,13 @@ class ConsoleServerPortTemplateCreateView(generic.ComponentCreateView): model_form = forms.ConsoleServerPortTemplateForm +@register_model_view(ConsoleServerPortTemplate, 'edit') class ConsoleServerPortTemplateEditView(generic.ObjectEditView): queryset = ConsoleServerPortTemplate.objects.all() form = forms.ConsoleServerPortTemplateForm +@register_model_view(ConsoleServerPortTemplate, 'delete') class ConsoleServerPortTemplateDeleteView(generic.ObjectDeleteView): queryset = ConsoleServerPortTemplate.objects.all() @@ -1288,11 +1377,13 @@ class PowerPortTemplateCreateView(generic.ComponentCreateView): model_form = forms.PowerPortTemplateForm +@register_model_view(PowerPortTemplate, 'edit') class PowerPortTemplateEditView(generic.ObjectEditView): queryset = PowerPortTemplate.objects.all() form = forms.PowerPortTemplateForm +@register_model_view(PowerPortTemplate, 'delete') class PowerPortTemplateDeleteView(generic.ObjectDeleteView): queryset = PowerPortTemplate.objects.all() @@ -1322,11 +1413,13 @@ class PowerOutletTemplateCreateView(generic.ComponentCreateView): model_form = forms.PowerOutletTemplateForm +@register_model_view(PowerOutletTemplate, 'edit') class PowerOutletTemplateEditView(generic.ObjectEditView): queryset = PowerOutletTemplate.objects.all() form = forms.PowerOutletTemplateForm +@register_model_view(PowerOutletTemplate, 'delete') class PowerOutletTemplateDeleteView(generic.ObjectDeleteView): queryset = PowerOutletTemplate.objects.all() @@ -1356,11 +1449,13 @@ class InterfaceTemplateCreateView(generic.ComponentCreateView): model_form = forms.InterfaceTemplateForm +@register_model_view(InterfaceTemplate, 'edit') class InterfaceTemplateEditView(generic.ObjectEditView): queryset = InterfaceTemplate.objects.all() form = forms.InterfaceTemplateForm +@register_model_view(InterfaceTemplate, 'delete') class InterfaceTemplateDeleteView(generic.ObjectDeleteView): queryset = InterfaceTemplate.objects.all() @@ -1390,11 +1485,13 @@ class FrontPortTemplateCreateView(generic.ComponentCreateView): model_form = forms.FrontPortTemplateForm +@register_model_view(FrontPortTemplate, 'edit') class FrontPortTemplateEditView(generic.ObjectEditView): queryset = FrontPortTemplate.objects.all() form = forms.FrontPortTemplateForm +@register_model_view(FrontPortTemplate, 'delete') class FrontPortTemplateDeleteView(generic.ObjectDeleteView): queryset = FrontPortTemplate.objects.all() @@ -1424,11 +1521,13 @@ class RearPortTemplateCreateView(generic.ComponentCreateView): model_form = forms.RearPortTemplateForm +@register_model_view(RearPortTemplate, 'edit') class RearPortTemplateEditView(generic.ObjectEditView): queryset = RearPortTemplate.objects.all() form = forms.RearPortTemplateForm +@register_model_view(RearPortTemplate, 'delete') class RearPortTemplateDeleteView(generic.ObjectDeleteView): queryset = RearPortTemplate.objects.all() @@ -1458,11 +1557,13 @@ class ModuleBayTemplateCreateView(generic.ComponentCreateView): model_form = forms.ModuleBayTemplateForm +@register_model_view(ModuleBayTemplate, 'edit') class ModuleBayTemplateEditView(generic.ObjectEditView): queryset = ModuleBayTemplate.objects.all() form = forms.ModuleBayTemplateForm +@register_model_view(ModuleBayTemplate, 'delete') class ModuleBayTemplateDeleteView(generic.ObjectDeleteView): queryset = ModuleBayTemplate.objects.all() @@ -1492,11 +1593,13 @@ class DeviceBayTemplateCreateView(generic.ComponentCreateView): model_form = forms.DeviceBayTemplateForm +@register_model_view(DeviceBayTemplate, 'edit') class DeviceBayTemplateEditView(generic.ObjectEditView): queryset = DeviceBayTemplate.objects.all() form = forms.DeviceBayTemplateForm +@register_model_view(DeviceBayTemplate, 'delete') class DeviceBayTemplateDeleteView(generic.ObjectDeleteView): queryset = DeviceBayTemplate.objects.all() @@ -1537,11 +1640,13 @@ class InventoryItemTemplateCreateView(generic.ComponentCreateView): return instance +@register_model_view(InventoryItemTemplate, 'edit') class InventoryItemTemplateEditView(generic.ObjectEditView): queryset = InventoryItemTemplate.objects.all() form = forms.InventoryItemTemplateForm +@register_model_view(InventoryItemTemplate, 'delete') class InventoryItemTemplateDeleteView(generic.ObjectDeleteView): queryset = InventoryItemTemplate.objects.all() @@ -1575,6 +1680,7 @@ class DeviceRoleListView(generic.ObjectListView): table = tables.DeviceRoleTable +@register_model_view(DeviceRole) class DeviceRoleView(generic.ObjectView): queryset = DeviceRole.objects.all() @@ -1592,11 +1698,13 @@ class DeviceRoleView(generic.ObjectView): } +@register_model_view(DeviceRole, 'edit') class DeviceRoleEditView(generic.ObjectEditView): queryset = DeviceRole.objects.all() form = forms.DeviceRoleForm +@register_model_view(DeviceRole, 'delete') class DeviceRoleDeleteView(generic.ObjectDeleteView): queryset = DeviceRole.objects.all() @@ -1639,6 +1747,7 @@ class PlatformListView(generic.ObjectListView): filterset_form = forms.PlatformFilterForm +@register_model_view(Platform) class PlatformView(generic.ObjectView): queryset = Platform.objects.all() @@ -1655,11 +1764,13 @@ class PlatformView(generic.ObjectView): } +@register_model_view(Platform, 'edit') class PlatformEditView(generic.ObjectEditView): queryset = Platform.objects.all() form = forms.PlatformForm +@register_model_view(Platform, 'delete') class PlatformDeleteView(generic.ObjectDeleteView): queryset = Platform.objects.all() @@ -1694,6 +1805,7 @@ class DeviceListView(generic.ObjectListView): template_name = 'dcim/device_list.html' +@register_model_view(Device) class DeviceView(generic.ObjectView): queryset = Device.objects.all() @@ -1716,6 +1828,18 @@ class DeviceView(generic.ObjectView): } +@register_model_view(Device, 'edit') +class DeviceEditView(generic.ObjectEditView): + queryset = Device.objects.all() + form = forms.DeviceForm + template_name = 'dcim/device_edit.html' + + +@register_model_view(Device, 'delete') +class DeviceDeleteView(generic.ObjectDeleteView): + queryset = Device.objects.all() + + @register_model_view(Device, 'consoleports', path='console-ports') class DeviceConsolePortsView(DeviceComponentsView): child_model = ConsolePort @@ -1862,16 +1986,6 @@ class DeviceConfigContextView(ObjectConfigContextView): ) -class DeviceEditView(generic.ObjectEditView): - queryset = Device.objects.all() - form = forms.DeviceForm - template_name = 'dcim/device_edit.html' - - -class DeviceDeleteView(generic.ObjectDeleteView): - queryset = Device.objects.all() - - class DeviceBulkImportView(generic.BulkImportView): queryset = Device.objects.all() model_form = forms.DeviceCSVForm @@ -1988,15 +2102,18 @@ class ModuleListView(generic.ObjectListView): table = tables.ModuleTable +@register_model_view(Module) class ModuleView(generic.ObjectView): queryset = Module.objects.all() +@register_model_view(Module, 'edit') class ModuleEditView(generic.ObjectEditView): queryset = Module.objects.all() form = forms.ModuleForm +@register_model_view(Module, 'delete') class ModuleDeleteView(generic.ObjectDeleteView): queryset = Module.objects.all() @@ -2032,6 +2149,7 @@ class ConsolePortListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(ConsolePort) class ConsolePortView(generic.ObjectView): queryset = ConsolePort.objects.all() @@ -2042,11 +2160,13 @@ class ConsolePortCreateView(generic.ComponentCreateView): model_form = forms.ConsolePortForm +@register_model_view(ConsolePort, 'edit') class ConsolePortEditView(generic.ObjectEditView): queryset = ConsolePort.objects.all() form = forms.ConsolePortForm +@register_model_view(ConsolePort, 'delete') class ConsolePortDeleteView(generic.ObjectDeleteView): queryset = ConsolePort.objects.all() @@ -2078,6 +2198,10 @@ class ConsolePortBulkDeleteView(generic.BulkDeleteView): table = tables.ConsolePortTable +# Trace view +register_model_view(ConsolePort, 'trace', kwargs={'model': ConsolePort})(PathTraceView) + + # # Console server ports # @@ -2090,6 +2214,7 @@ class ConsoleServerPortListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(ConsoleServerPort) class ConsoleServerPortView(generic.ObjectView): queryset = ConsoleServerPort.objects.all() @@ -2100,11 +2225,13 @@ class ConsoleServerPortCreateView(generic.ComponentCreateView): model_form = forms.ConsoleServerPortForm +@register_model_view(ConsoleServerPort, 'edit') class ConsoleServerPortEditView(generic.ObjectEditView): queryset = ConsoleServerPort.objects.all() form = forms.ConsoleServerPortForm +@register_model_view(ConsoleServerPort, 'delete') class ConsoleServerPortDeleteView(generic.ObjectDeleteView): queryset = ConsoleServerPort.objects.all() @@ -2136,6 +2263,10 @@ class ConsoleServerPortBulkDeleteView(generic.BulkDeleteView): table = tables.ConsoleServerPortTable +# Trace view +register_model_view(ConsoleServerPort, 'trace', kwargs={'model': ConsoleServerPort})(PathTraceView) + + # # Power ports # @@ -2148,6 +2279,7 @@ class PowerPortListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(PowerPort) class PowerPortView(generic.ObjectView): queryset = PowerPort.objects.all() @@ -2158,11 +2290,13 @@ class PowerPortCreateView(generic.ComponentCreateView): model_form = forms.PowerPortForm +@register_model_view(PowerPort, 'edit') class PowerPortEditView(generic.ObjectEditView): queryset = PowerPort.objects.all() form = forms.PowerPortForm +@register_model_view(PowerPort, 'delete') class PowerPortDeleteView(generic.ObjectDeleteView): queryset = PowerPort.objects.all() @@ -2194,6 +2328,10 @@ class PowerPortBulkDeleteView(generic.BulkDeleteView): table = tables.PowerPortTable +# Trace view +register_model_view(PowerPort, 'trace', kwargs={'model': PowerPort})(PathTraceView) + + # # Power outlets # @@ -2206,6 +2344,7 @@ class PowerOutletListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(PowerOutlet) class PowerOutletView(generic.ObjectView): queryset = PowerOutlet.objects.all() @@ -2216,11 +2355,13 @@ class PowerOutletCreateView(generic.ComponentCreateView): model_form = forms.PowerOutletForm +@register_model_view(PowerOutlet, 'edit') class PowerOutletEditView(generic.ObjectEditView): queryset = PowerOutlet.objects.all() form = forms.PowerOutletForm +@register_model_view(PowerOutlet, 'delete') class PowerOutletDeleteView(generic.ObjectDeleteView): queryset = PowerOutlet.objects.all() @@ -2252,6 +2393,10 @@ class PowerOutletBulkDeleteView(generic.BulkDeleteView): table = tables.PowerOutletTable +# Trace view +register_model_view(PowerOutlet, 'trace', kwargs={'model': PowerOutlet})(PathTraceView) + + # # Interfaces # @@ -2264,6 +2409,7 @@ class InterfaceListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(Interface) class InterfaceView(generic.ObjectView): queryset = Interface.objects.all() @@ -2318,11 +2464,13 @@ class InterfaceCreateView(generic.ComponentCreateView): model_form = forms.InterfaceForm +@register_model_view(Interface, 'edit') class InterfaceEditView(generic.ObjectEditView): queryset = Interface.objects.all() form = forms.InterfaceForm +@register_model_view(Interface, 'delete') class InterfaceDeleteView(generic.ObjectDeleteView): queryset = Interface.objects.all() @@ -2354,6 +2502,10 @@ class InterfaceBulkDeleteView(generic.BulkDeleteView): table = tables.InterfaceTable +# Trace view +register_model_view(Interface, 'trace', kwargs={'model': Interface})(PathTraceView) + + # # Front ports # @@ -2366,6 +2518,7 @@ class FrontPortListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(FrontPort) class FrontPortView(generic.ObjectView): queryset = FrontPort.objects.all() @@ -2376,11 +2529,13 @@ class FrontPortCreateView(generic.ComponentCreateView): model_form = forms.FrontPortForm +@register_model_view(FrontPort, 'edit') class FrontPortEditView(generic.ObjectEditView): queryset = FrontPort.objects.all() form = forms.FrontPortForm +@register_model_view(FrontPort, 'delete') class FrontPortDeleteView(generic.ObjectDeleteView): queryset = FrontPort.objects.all() @@ -2412,6 +2567,10 @@ class FrontPortBulkDeleteView(generic.BulkDeleteView): table = tables.FrontPortTable +# Trace view +register_model_view(FrontPort, 'trace', kwargs={'model': FrontPort})(PathTraceView) + + # # Rear ports # @@ -2424,6 +2583,7 @@ class RearPortListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(RearPort) class RearPortView(generic.ObjectView): queryset = RearPort.objects.all() @@ -2434,11 +2594,13 @@ class RearPortCreateView(generic.ComponentCreateView): model_form = forms.RearPortForm +@register_model_view(RearPort, 'edit') class RearPortEditView(generic.ObjectEditView): queryset = RearPort.objects.all() form = forms.RearPortForm +@register_model_view(RearPort, 'delete') class RearPortDeleteView(generic.ObjectDeleteView): queryset = RearPort.objects.all() @@ -2470,6 +2632,10 @@ class RearPortBulkDeleteView(generic.BulkDeleteView): table = tables.RearPortTable +# Trace view +register_model_view(RearPort, 'trace', kwargs={'model': RearPort})(PathTraceView) + + # # Module bays # @@ -2482,6 +2648,7 @@ class ModuleBayListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(ModuleBay) class ModuleBayView(generic.ObjectView): queryset = ModuleBay.objects.all() @@ -2492,11 +2659,13 @@ class ModuleBayCreateView(generic.ComponentCreateView): model_form = forms.ModuleBayForm +@register_model_view(ModuleBay, 'edit') class ModuleBayEditView(generic.ObjectEditView): queryset = ModuleBay.objects.all() form = forms.ModuleBayForm +@register_model_view(ModuleBay, 'delete') class ModuleBayDeleteView(generic.ObjectDeleteView): queryset = ModuleBay.objects.all() @@ -2536,6 +2705,7 @@ class DeviceBayListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(DeviceBay) class DeviceBayView(generic.ObjectView): queryset = DeviceBay.objects.all() @@ -2546,15 +2716,18 @@ class DeviceBayCreateView(generic.ComponentCreateView): model_form = forms.DeviceBayForm +@register_model_view(DeviceBay, 'edit') class DeviceBayEditView(generic.ObjectEditView): queryset = DeviceBay.objects.all() form = forms.DeviceBayForm +@register_model_view(DeviceBay, 'delete') class DeviceBayDeleteView(generic.ObjectDeleteView): queryset = DeviceBay.objects.all() +@register_model_view(DeviceBay, 'populate') class DeviceBayPopulateView(generic.ObjectEditView): queryset = DeviceBay.objects.all() @@ -2588,6 +2761,7 @@ class DeviceBayPopulateView(generic.ObjectEditView): }) +@register_model_view(DeviceBay, 'depopulate') class DeviceBayDepopulateView(generic.ObjectEditView): queryset = DeviceBay.objects.all() @@ -2657,10 +2831,12 @@ class InventoryItemListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(InventoryItem) class InventoryItemView(generic.ObjectView): queryset = InventoryItem.objects.all() +@register_model_view(InventoryItem, 'edit') class InventoryItemEditView(generic.ObjectEditView): queryset = InventoryItem.objects.all() form = forms.InventoryItemForm @@ -2683,6 +2859,7 @@ class InventoryItemCreateView(generic.ComponentCreateView): return instance +@register_model_view(InventoryItem, 'delete') class InventoryItemDeleteView(generic.ObjectDeleteView): queryset = InventoryItem.objects.all() @@ -2723,6 +2900,7 @@ class InventoryItemRoleListView(generic.ObjectListView): table = tables.InventoryItemRoleTable +@register_model_view(InventoryItemRole) class InventoryItemRoleView(generic.ObjectView): queryset = InventoryItemRole.objects.all() @@ -2732,11 +2910,13 @@ class InventoryItemRoleView(generic.ObjectView): } +@register_model_view(InventoryItemRole, 'edit') class InventoryItemRoleEditView(generic.ObjectEditView): queryset = InventoryItemRole.objects.all() form = forms.InventoryItemRoleForm +@register_model_view(InventoryItemRole, 'delete') class InventoryItemRoleDeleteView(generic.ObjectDeleteView): queryset = InventoryItemRole.objects.all() @@ -2892,65 +3072,12 @@ class CableListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(Cable) class CableView(generic.ObjectView): queryset = Cable.objects.all() -class PathTraceView(generic.ObjectView): - """ - Trace a cable path beginning from the given path endpoint (origin). - """ - additional_permissions = ['dcim.view_cable'] - template_name = 'dcim/cable_trace.html' - - def dispatch(self, request, *args, **kwargs): - model = kwargs.pop('model') - self.queryset = model.objects.all() - - return super().dispatch(request, *args, **kwargs) - - def get_extra_context(self, request, instance): - related_paths = [] - - # If tracing a PathEndpoint, locate the CablePath (if one exists) by its origin - if isinstance(instance, PathEndpoint): - path = instance._path - - # Otherwise, find all CablePaths which traverse the specified object - else: - related_paths = CablePath.objects.filter(_nodes__contains=instance) - # Check for specification of a particular path (when tracing pass-through ports) - try: - path_id = int(request.GET.get('cablepath_id')) - except TypeError: - path_id = None - if path_id in list(related_paths.values_list('pk', flat=True)): - path = CablePath.objects.get(pk=path_id) - else: - path = related_paths.first() - - # No paths found - if path is None: - return { - 'path': None - } - - # Get the total length of the cable and whether the length is definitive (fully defined) - total_length, is_definitive = path.get_total_length() if path else (None, False) - - # Determine the path to the SVG trace image - api_viewname = f"{path.origin_type.app_label}-api:{path.origin_type.model}-trace" - svg_url = f"{reverse(api_viewname, kwargs={'pk': path.origins[0].pk})}?render=svg" - - return { - 'path': path, - 'related_paths': related_paths, - 'total_length': total_length, - 'is_definitive': is_definitive, - 'svg_url': svg_url, - } - - +@register_model_view(Cable, 'edit') class CableEditView(generic.ObjectEditView): queryset = Cable.objects.all() template_name = 'dcim/cable_edit.html' @@ -2984,6 +3111,7 @@ class CableEditView(generic.ObjectEditView): return obj +@register_model_view(Cable, 'delete') class CableDeleteView(generic.ObjectDeleteView): queryset = Cable.objects.all() @@ -3072,6 +3200,7 @@ class VirtualChassisListView(generic.ObjectListView): filterset_form = forms.VirtualChassisFilterForm +@register_model_view(VirtualChassis) class VirtualChassisView(generic.ObjectView): queryset = VirtualChassis.objects.all() @@ -3089,6 +3218,7 @@ class VirtualChassisCreateView(generic.ObjectEditView): template_name = 'dcim/virtualchassis_add.html' +@register_model_view(VirtualChassis, 'edit') class VirtualChassisEditView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View): queryset = VirtualChassis.objects.all() @@ -3157,10 +3287,12 @@ class VirtualChassisEditView(ObjectPermissionRequiredMixin, GetReturnURLMixin, V }) +@register_model_view(VirtualChassis, 'delete') class VirtualChassisDeleteView(generic.ObjectDeleteView): queryset = VirtualChassis.objects.all() +@register_model_view(VirtualChassis, 'add_member', path='add-member') class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View): queryset = VirtualChassis.objects.all() @@ -3299,6 +3431,7 @@ class PowerPanelListView(generic.ObjectListView): table = tables.PowerPanelTable +@register_model_view(PowerPanel) class PowerPanelView(generic.ObjectView): queryset = PowerPanel.objects.all() @@ -3317,11 +3450,13 @@ class PowerPanelView(generic.ObjectView): } +@register_model_view(PowerPanel, 'edit') class PowerPanelEditView(generic.ObjectEditView): queryset = PowerPanel.objects.all() form = forms.PowerPanelForm +@register_model_view(PowerPanel, 'delete') class PowerPanelDeleteView(generic.ObjectDeleteView): queryset = PowerPanel.objects.all() @@ -3358,15 +3493,18 @@ class PowerFeedListView(generic.ObjectListView): table = tables.PowerFeedTable +@register_model_view(PowerFeed) class PowerFeedView(generic.ObjectView): queryset = PowerFeed.objects.all() +@register_model_view(PowerFeed, 'edit') class PowerFeedEditView(generic.ObjectEditView): queryset = PowerFeed.objects.all() form = forms.PowerFeedForm +@register_model_view(PowerFeed, 'delete') class PowerFeedDeleteView(generic.ObjectDeleteView): queryset = PowerFeed.objects.all() @@ -3392,3 +3530,7 @@ class PowerFeedBulkDeleteView(generic.BulkDeleteView): queryset = PowerFeed.objects.all() filterset = filtersets.PowerFeedFilterSet table = tables.PowerFeedTable + + +# Trace view +register_model_view(PowerFeed, 'trace', kwargs={'model': PowerFeed})(PathTraceView) diff --git a/netbox/extras/urls.py b/netbox/extras/urls.py index 18d0314bf..ecc4c116c 100644 --- a/netbox/extras/urls.py +++ b/netbox/extras/urls.py @@ -13,9 +13,6 @@ urlpatterns = [ path('custom-fields/import/', views.CustomFieldBulkImportView.as_view(), name='customfield_import'), path('custom-fields/edit/', views.CustomFieldBulkEditView.as_view(), name='customfield_bulk_edit'), path('custom-fields/delete/', views.CustomFieldBulkDeleteView.as_view(), name='customfield_bulk_delete'), - path('custom-fields//', views.CustomFieldView.as_view(), name='customfield'), - path('custom-fields//edit/', views.CustomFieldEditView.as_view(), name='customfield_edit'), - path('custom-fields//delete/', views.CustomFieldDeleteView.as_view(), name='customfield_delete'), path('custom-fields//', include(get_model_urls('extras', 'customfield'))), # Custom links @@ -24,9 +21,6 @@ urlpatterns = [ path('custom-links/import/', views.CustomLinkBulkImportView.as_view(), name='customlink_import'), path('custom-links/edit/', views.CustomLinkBulkEditView.as_view(), name='customlink_bulk_edit'), path('custom-links/delete/', views.CustomLinkBulkDeleteView.as_view(), name='customlink_bulk_delete'), - path('custom-links//', views.CustomLinkView.as_view(), name='customlink'), - path('custom-links//edit/', views.CustomLinkEditView.as_view(), name='customlink_edit'), - path('custom-links//delete/', views.CustomLinkDeleteView.as_view(), name='customlink_delete'), path('custom-links//', include(get_model_urls('extras', 'customlink'))), # Export templates @@ -35,9 +29,6 @@ urlpatterns = [ path('export-templates/import/', views.ExportTemplateBulkImportView.as_view(), name='exporttemplate_import'), path('export-templates/edit/', views.ExportTemplateBulkEditView.as_view(), name='exporttemplate_bulk_edit'), path('export-templates/delete/', views.ExportTemplateBulkDeleteView.as_view(), name='exporttemplate_bulk_delete'), - path('export-templates//', views.ExportTemplateView.as_view(), name='exporttemplate'), - path('export-templates//edit/', views.ExportTemplateEditView.as_view(), name='exporttemplate_edit'), - path('export-templates//delete/', views.ExportTemplateDeleteView.as_view(), name='exporttemplate_delete'), path('export-templates//', include(get_model_urls('extras', 'exporttemplate'))), # Webhooks @@ -46,9 +37,6 @@ urlpatterns = [ path('webhooks/import/', views.WebhookBulkImportView.as_view(), name='webhook_import'), path('webhooks/edit/', views.WebhookBulkEditView.as_view(), name='webhook_bulk_edit'), path('webhooks/delete/', views.WebhookBulkDeleteView.as_view(), name='webhook_bulk_delete'), - path('webhooks//', views.WebhookView.as_view(), name='webhook'), - path('webhooks//edit/', views.WebhookEditView.as_view(), name='webhook_edit'), - path('webhooks//delete/', views.WebhookDeleteView.as_view(), name='webhook_delete'), path('webhooks//', include(get_model_urls('extras', 'webhook'))), # Tags @@ -57,9 +45,6 @@ urlpatterns = [ path('tags/import/', views.TagBulkImportView.as_view(), name='tag_import'), path('tags/edit/', views.TagBulkEditView.as_view(), name='tag_bulk_edit'), path('tags/delete/', views.TagBulkDeleteView.as_view(), name='tag_bulk_delete'), - path('tags//', views.TagView.as_view(), name='tag'), - path('tags//edit/', views.TagEditView.as_view(), name='tag_edit'), - path('tags//delete/', views.TagDeleteView.as_view(), name='tag_delete'), path('tags//', include(get_model_urls('extras', 'tag'))), # Config contexts @@ -67,29 +52,22 @@ urlpatterns = [ path('config-contexts/add/', views.ConfigContextEditView.as_view(), name='configcontext_add'), path('config-contexts/edit/', views.ConfigContextBulkEditView.as_view(), name='configcontext_bulk_edit'), path('config-contexts/delete/', views.ConfigContextBulkDeleteView.as_view(), name='configcontext_bulk_delete'), - path('config-contexts//', views.ConfigContextView.as_view(), name='configcontext'), - path('config-contexts//edit/', views.ConfigContextEditView.as_view(), name='configcontext_edit'), - path('config-contexts//delete/', views.ConfigContextDeleteView.as_view(), name='configcontext_delete'), path('config-contexts//', include(get_model_urls('extras', 'configcontext'))), # Image attachments path('image-attachments/add/', views.ImageAttachmentEditView.as_view(), name='imageattachment_add'), - path('image-attachments//edit/', views.ImageAttachmentEditView.as_view(), name='imageattachment_edit'), - path('image-attachments//delete/', views.ImageAttachmentDeleteView.as_view(), name='imageattachment_delete'), + path('image-attachments//', include(get_model_urls('extras', 'imageattachment'))), # Journal entries path('journal-entries/', views.JournalEntryListView.as_view(), name='journalentry_list'), path('journal-entries/add/', views.JournalEntryEditView.as_view(), name='journalentry_add'), path('journal-entries/edit/', views.JournalEntryBulkEditView.as_view(), name='journalentry_bulk_edit'), path('journal-entries/delete/', views.JournalEntryBulkDeleteView.as_view(), name='journalentry_bulk_delete'), - path('journal-entries//', views.JournalEntryView.as_view(), name='journalentry'), - path('journal-entries//edit/', views.JournalEntryEditView.as_view(), name='journalentry_edit'), - path('journal-entries//delete/', views.JournalEntryDeleteView.as_view(), name='journalentry_delete'), path('journal-entries//', include(get_model_urls('extras', 'journalentry'))), # Change logging path('changelog/', views.ObjectChangeListView.as_view(), name='objectchange_list'), - path('changelog//', views.ObjectChangeView.as_view(), name='objectchange'), + path('changelog//', include(get_model_urls('extras', 'objectchange'))), # Reports path('reports/', views.ReportListView.as_view(), name='report_list'), diff --git a/netbox/extras/views.py b/netbox/extras/views.py index e48fd672b..337980e94 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -12,7 +12,7 @@ from netbox.views import generic from utilities.forms import ConfirmationForm from utilities.htmx import is_htmx from utilities.utils import copy_safe_request, count_related, get_viewname, normalize_querydict, shallow_compare_dict -from utilities.views import ContentTypePermissionRequiredMixin +from utilities.views import ContentTypePermissionRequiredMixin, register_model_view from . import filtersets, forms, tables from .choices import JobResultStatusChoices from .models import * @@ -31,15 +31,18 @@ class CustomFieldListView(generic.ObjectListView): table = tables.CustomFieldTable +@register_model_view(CustomField) class CustomFieldView(generic.ObjectView): queryset = CustomField.objects.all() +@register_model_view(CustomField, 'edit') class CustomFieldEditView(generic.ObjectEditView): queryset = CustomField.objects.all() form = forms.CustomFieldForm +@register_model_view(CustomField, 'delete') class CustomFieldDeleteView(generic.ObjectDeleteView): queryset = CustomField.objects.all() @@ -74,15 +77,18 @@ class CustomLinkListView(generic.ObjectListView): table = tables.CustomLinkTable +@register_model_view(CustomLink) class CustomLinkView(generic.ObjectView): queryset = CustomLink.objects.all() +@register_model_view(CustomLink, 'edit') class CustomLinkEditView(generic.ObjectEditView): queryset = CustomLink.objects.all() form = forms.CustomLinkForm +@register_model_view(CustomLink, 'delete') class CustomLinkDeleteView(generic.ObjectDeleteView): queryset = CustomLink.objects.all() @@ -117,15 +123,18 @@ class ExportTemplateListView(generic.ObjectListView): table = tables.ExportTemplateTable +@register_model_view(ExportTemplate) class ExportTemplateView(generic.ObjectView): queryset = ExportTemplate.objects.all() +@register_model_view(ExportTemplate, 'edit') class ExportTemplateEditView(generic.ObjectEditView): queryset = ExportTemplate.objects.all() form = forms.ExportTemplateForm +@register_model_view(ExportTemplate, 'delete') class ExportTemplateDeleteView(generic.ObjectDeleteView): queryset = ExportTemplate.objects.all() @@ -160,15 +169,18 @@ class WebhookListView(generic.ObjectListView): table = tables.WebhookTable +@register_model_view(Webhook) class WebhookView(generic.ObjectView): queryset = Webhook.objects.all() +@register_model_view(Webhook, 'edit') class WebhookEditView(generic.ObjectEditView): queryset = Webhook.objects.all() form = forms.WebhookForm +@register_model_view(Webhook, 'delete') class WebhookDeleteView(generic.ObjectDeleteView): queryset = Webhook.objects.all() @@ -205,6 +217,7 @@ class TagListView(generic.ObjectListView): table = tables.TagTable +@register_model_view(Tag) class TagView(generic.ObjectView): queryset = Tag.objects.all() @@ -230,11 +243,13 @@ class TagView(generic.ObjectView): } +@register_model_view(Tag, 'edit') class TagEditView(generic.ObjectEditView): queryset = Tag.objects.all() form = forms.TagForm +@register_model_view(Tag, 'delete') class TagDeleteView(generic.ObjectDeleteView): queryset = Tag.objects.all() @@ -272,6 +287,7 @@ class ConfigContextListView(generic.ObjectListView): actions = ('add', 'bulk_edit', 'bulk_delete') +@register_model_view(ConfigContext) class ConfigContextView(generic.ObjectView): queryset = ConfigContext.objects.all() @@ -309,6 +325,7 @@ class ConfigContextView(generic.ObjectView): } +@register_model_view(ConfigContext, 'edit') class ConfigContextEditView(generic.ObjectEditView): queryset = ConfigContext.objects.all() form = forms.ConfigContextForm @@ -321,6 +338,7 @@ class ConfigContextBulkEditView(generic.BulkEditView): form = forms.ConfigContextBulkEditForm +@register_model_view(ConfigContext, 'delete') class ConfigContextDeleteView(generic.ObjectDeleteView): queryset = ConfigContext.objects.all() @@ -368,6 +386,7 @@ class ObjectChangeListView(generic.ObjectListView): actions = ('export',) +@register_model_view(ObjectChange) class ObjectChangeView(generic.ObjectView): queryset = ObjectChange.objects.all() @@ -425,6 +444,7 @@ class ObjectChangeView(generic.ObjectView): # Image attachments # +@register_model_view(ImageAttachment, 'edit') class ImageAttachmentEditView(generic.ObjectEditView): queryset = ImageAttachment.objects.all() form = forms.ImageAttachmentForm @@ -447,6 +467,7 @@ class ImageAttachmentEditView(generic.ObjectEditView): } +@register_model_view(ImageAttachment, 'delete') class ImageAttachmentDeleteView(generic.ObjectDeleteView): queryset = ImageAttachment.objects.all() @@ -466,10 +487,12 @@ class JournalEntryListView(generic.ObjectListView): actions = ('export', 'bulk_edit', 'bulk_delete') +@register_model_view(JournalEntry) class JournalEntryView(generic.ObjectView): queryset = JournalEntry.objects.all() +@register_model_view(JournalEntry, 'edit') class JournalEntryEditView(generic.ObjectEditView): queryset = JournalEntry.objects.all() form = forms.JournalEntryForm @@ -487,6 +510,7 @@ class JournalEntryEditView(generic.ObjectEditView): return reverse(viewname, kwargs={'pk': obj.pk}) +@register_model_view(JournalEntry, 'delete') class JournalEntryDeleteView(generic.ObjectDeleteView): queryset = JournalEntry.objects.all() diff --git a/netbox/ipam/urls.py b/netbox/ipam/urls.py index d5594eeb9..032ddf498 100644 --- a/netbox/ipam/urls.py +++ b/netbox/ipam/urls.py @@ -12,9 +12,6 @@ urlpatterns = [ path('asns/import/', views.ASNBulkImportView.as_view(), name='asn_import'), path('asns/edit/', views.ASNBulkEditView.as_view(), name='asn_bulk_edit'), path('asns/delete/', views.ASNBulkDeleteView.as_view(), name='asn_bulk_delete'), - path('asns//', views.ASNView.as_view(), name='asn'), - path('asns//edit/', views.ASNEditView.as_view(), name='asn_edit'), - path('asns//delete/', views.ASNDeleteView.as_view(), name='asn_delete'), path('asns//', include(get_model_urls('ipam', 'asn'))), # VRFs @@ -23,9 +20,6 @@ urlpatterns = [ path('vrfs/import/', views.VRFBulkImportView.as_view(), name='vrf_import'), path('vrfs/edit/', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'), path('vrfs/delete/', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'), - path('vrfs//', views.VRFView.as_view(), name='vrf'), - path('vrfs//edit/', views.VRFEditView.as_view(), name='vrf_edit'), - path('vrfs//delete/', views.VRFDeleteView.as_view(), name='vrf_delete'), path('vrfs//', include(get_model_urls('ipam', 'vrf'))), # Route targets @@ -34,9 +28,6 @@ urlpatterns = [ path('route-targets/import/', views.RouteTargetBulkImportView.as_view(), name='routetarget_import'), path('route-targets/edit/', views.RouteTargetBulkEditView.as_view(), name='routetarget_bulk_edit'), path('route-targets/delete/', views.RouteTargetBulkDeleteView.as_view(), name='routetarget_bulk_delete'), - path('route-targets//', views.RouteTargetView.as_view(), name='routetarget'), - path('route-targets//edit/', views.RouteTargetEditView.as_view(), name='routetarget_edit'), - path('route-targets//delete/', views.RouteTargetDeleteView.as_view(), name='routetarget_delete'), path('route-targets//', include(get_model_urls('ipam', 'routetarget'))), # RIRs @@ -45,9 +36,6 @@ urlpatterns = [ path('rirs/import/', views.RIRBulkImportView.as_view(), name='rir_import'), path('rirs/edit/', views.RIRBulkEditView.as_view(), name='rir_bulk_edit'), path('rirs/delete/', views.RIRBulkDeleteView.as_view(), name='rir_bulk_delete'), - path('rirs//', views.RIRView.as_view(), name='rir'), - path('rirs//edit/', views.RIREditView.as_view(), name='rir_edit'), - path('rirs//delete/', views.RIRDeleteView.as_view(), name='rir_delete'), path('rirs//', include(get_model_urls('ipam', 'rir'))), # Aggregates @@ -56,9 +44,6 @@ urlpatterns = [ path('aggregates/import/', views.AggregateBulkImportView.as_view(), name='aggregate_import'), path('aggregates/edit/', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'), path('aggregates/delete/', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'), - path('aggregates//', views.AggregateView.as_view(), name='aggregate'), - path('aggregates//edit/', views.AggregateEditView.as_view(), name='aggregate_edit'), - path('aggregates//delete/', views.AggregateDeleteView.as_view(), name='aggregate_delete'), path('aggregates//', include(get_model_urls('ipam', 'aggregate'))), # Roles @@ -67,9 +52,6 @@ urlpatterns = [ path('roles/import/', views.RoleBulkImportView.as_view(), name='role_import'), path('roles/edit/', views.RoleBulkEditView.as_view(), name='role_bulk_edit'), path('roles/delete/', views.RoleBulkDeleteView.as_view(), name='role_bulk_delete'), - path('roles//', views.RoleView.as_view(), name='role'), - path('roles//edit/', views.RoleEditView.as_view(), name='role_edit'), - path('roles//delete/', views.RoleDeleteView.as_view(), name='role_delete'), path('roles//', include(get_model_urls('ipam', 'role'))), # Prefixes @@ -78,9 +60,6 @@ urlpatterns = [ path('prefixes/import/', views.PrefixBulkImportView.as_view(), name='prefix_import'), path('prefixes/edit/', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'), path('prefixes/delete/', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'), - path('prefixes//', views.PrefixView.as_view(), name='prefix'), - path('prefixes//edit/', views.PrefixEditView.as_view(), name='prefix_edit'), - path('prefixes//delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'), path('prefixes//', include(get_model_urls('ipam', 'prefix'))), # IP ranges @@ -89,9 +68,6 @@ urlpatterns = [ path('ip-ranges/import/', views.IPRangeBulkImportView.as_view(), name='iprange_import'), path('ip-ranges/edit/', views.IPRangeBulkEditView.as_view(), name='iprange_bulk_edit'), path('ip-ranges/delete/', views.IPRangeBulkDeleteView.as_view(), name='iprange_bulk_delete'), - path('ip-ranges//', views.IPRangeView.as_view(), name='iprange'), - path('ip-ranges//edit/', views.IPRangeEditView.as_view(), name='iprange_edit'), - path('ip-ranges//delete/', views.IPRangeDeleteView.as_view(), name='iprange_delete'), path('ip-ranges//', include(get_model_urls('ipam', 'iprange'))), # IP addresses @@ -102,9 +78,6 @@ urlpatterns = [ path('ip-addresses/edit/', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'), path('ip-addresses/delete/', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'), path('ip-addresses/assign/', views.IPAddressAssignView.as_view(), name='ipaddress_assign'), - path('ip-addresses//', views.IPAddressView.as_view(), name='ipaddress'), - path('ip-addresses//edit/', views.IPAddressEditView.as_view(), name='ipaddress_edit'), - path('ip-addresses//delete/', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'), path('ip-addresses//', include(get_model_urls('ipam', 'ipaddress'))), # FHRP groups @@ -113,15 +86,11 @@ urlpatterns = [ path('fhrp-groups/import/', views.FHRPGroupBulkImportView.as_view(), name='fhrpgroup_import'), path('fhrp-groups/edit/', views.FHRPGroupBulkEditView.as_view(), name='fhrpgroup_bulk_edit'), path('fhrp-groups/delete/', views.FHRPGroupBulkDeleteView.as_view(), name='fhrpgroup_bulk_delete'), - path('fhrp-groups//', views.FHRPGroupView.as_view(), name='fhrpgroup'), - path('fhrp-groups//edit/', views.FHRPGroupEditView.as_view(), name='fhrpgroup_edit'), - path('fhrp-groups//delete/', views.FHRPGroupDeleteView.as_view(), name='fhrpgroup_delete'), path('fhrp-groups//', include(get_model_urls('ipam', 'fhrpgroup'))), # FHRP group assignments path('fhrp-group-assignments/add/', views.FHRPGroupAssignmentEditView.as_view(), name='fhrpgroupassignment_add'), - path('fhrp-group-assignments//edit/', views.FHRPGroupAssignmentEditView.as_view(), name='fhrpgroupassignment_edit'), - path('fhrp-group-assignments//delete/', views.FHRPGroupAssignmentDeleteView.as_view(), name='fhrpgroupassignment_delete'), + path('fhrp-group-assignments//', include(get_model_urls('ipam', 'fhrpgroupassignment'))), # VLAN groups path('vlan-groups/', views.VLANGroupListView.as_view(), name='vlangroup_list'), @@ -129,9 +98,6 @@ urlpatterns = [ path('vlan-groups/import/', views.VLANGroupBulkImportView.as_view(), name='vlangroup_import'), path('vlan-groups/edit/', views.VLANGroupBulkEditView.as_view(), name='vlangroup_bulk_edit'), path('vlan-groups/delete/', views.VLANGroupBulkDeleteView.as_view(), name='vlangroup_bulk_delete'), - path('vlan-groups//', views.VLANGroupView.as_view(), name='vlangroup'), - path('vlan-groups//edit/', views.VLANGroupEditView.as_view(), name='vlangroup_edit'), - path('vlan-groups//delete/', views.VLANGroupDeleteView.as_view(), name='vlangroup_delete'), path('vlan-groups//', include(get_model_urls('ipam', 'vlangroup'))), # VLANs @@ -140,9 +106,6 @@ urlpatterns = [ path('vlans/import/', views.VLANBulkImportView.as_view(), name='vlan_import'), path('vlans/edit/', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'), path('vlans/delete/', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'), - path('vlans//', views.VLANView.as_view(), name='vlan'), - path('vlans//edit/', views.VLANEditView.as_view(), name='vlan_edit'), - path('vlans//delete/', views.VLANDeleteView.as_view(), name='vlan_delete'), path('vlans//', include(get_model_urls('ipam', 'vlan'))), # Service templates @@ -151,9 +114,6 @@ urlpatterns = [ path('service-templates/import/', views.ServiceTemplateBulkImportView.as_view(), name='servicetemplate_import'), path('service-templates/edit/', views.ServiceTemplateBulkEditView.as_view(), name='servicetemplate_bulk_edit'), path('service-templates/delete/', views.ServiceTemplateBulkDeleteView.as_view(), name='servicetemplate_bulk_delete'), - path('service-templates//', views.ServiceTemplateView.as_view(), name='servicetemplate'), - path('service-templates//edit/', views.ServiceTemplateEditView.as_view(), name='servicetemplate_edit'), - path('service-templates//delete/', views.ServiceTemplateDeleteView.as_view(), name='servicetemplate_delete'), path('service-templates//', include(get_model_urls('ipam', 'servicetemplate'))), # Services @@ -162,9 +122,6 @@ urlpatterns = [ path('services/import/', views.ServiceBulkImportView.as_view(), name='service_import'), path('services/edit/', views.ServiceBulkEditView.as_view(), name='service_bulk_edit'), path('services/delete/', views.ServiceBulkDeleteView.as_view(), name='service_bulk_delete'), - path('services//', views.ServiceView.as_view(), name='service'), - path('services//edit/', views.ServiceEditView.as_view(), name='service_edit'), - path('services//delete/', views.ServiceDeleteView.as_view(), name='service_delete'), path('services//', include(get_model_urls('ipam', 'service'))), # L2VPN @@ -173,9 +130,6 @@ urlpatterns = [ path('l2vpns/import/', views.L2VPNBulkImportView.as_view(), name='l2vpn_import'), path('l2vpns/edit/', views.L2VPNBulkEditView.as_view(), name='l2vpn_bulk_edit'), path('l2vpns/delete/', views.L2VPNBulkDeleteView.as_view(), name='l2vpn_bulk_delete'), - path('l2vpns//', views.L2VPNView.as_view(), name='l2vpn'), - path('l2vpns//edit/', views.L2VPNEditView.as_view(), name='l2vpn_edit'), - path('l2vpns//delete/', views.L2VPNDeleteView.as_view(), name='l2vpn_delete'), path('l2vpns//', include(get_model_urls('ipam', 'l2vpn'))), # L2VPN terminations @@ -184,8 +138,5 @@ urlpatterns = [ path('l2vpn-terminations/import/', views.L2VPNTerminationBulkImportView.as_view(), name='l2vpntermination_import'), path('l2vpn-terminations/edit/', views.L2VPNTerminationBulkEditView.as_view(), name='l2vpntermination_bulk_edit'), path('l2vpn-terminations/delete/', views.L2VPNTerminationBulkDeleteView.as_view(), name='l2vpntermination_bulk_delete'), - path('l2vpn-terminations//', views.L2VPNTerminationView.as_view(), name='l2vpntermination'), - path('l2vpn-terminations//edit/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_edit'), - path('l2vpn-terminations//delete/', views.L2VPNTerminationDeleteView.as_view(), name='l2vpntermination_delete'), path('l2vpn-terminations//', include(get_model_urls('ipam', 'l2vpntermination'))), ] diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index fba577f02..a5f487f7d 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -34,6 +34,7 @@ class VRFListView(generic.ObjectListView): table = tables.VRFTable +@register_model_view(VRF) class VRFView(generic.ObjectView): queryset = VRF.objects.all() @@ -58,11 +59,13 @@ class VRFView(generic.ObjectView): } +@register_model_view(VRF, 'edit') class VRFEditView(generic.ObjectEditView): queryset = VRF.objects.all() form = forms.VRFForm +@register_model_view(VRF, 'delete') class VRFDeleteView(generic.ObjectDeleteView): queryset = VRF.objects.all() @@ -97,6 +100,7 @@ class RouteTargetListView(generic.ObjectListView): table = tables.RouteTargetTable +@register_model_view(RouteTarget) class RouteTargetView(generic.ObjectView): queryset = RouteTarget.objects.all() @@ -116,11 +120,13 @@ class RouteTargetView(generic.ObjectView): } +@register_model_view(RouteTarget, 'edit') class RouteTargetEditView(generic.ObjectEditView): queryset = RouteTarget.objects.all() form = forms.RouteTargetForm +@register_model_view(RouteTarget, 'delete') class RouteTargetDeleteView(generic.ObjectDeleteView): queryset = RouteTarget.objects.all() @@ -157,6 +163,7 @@ class RIRListView(generic.ObjectListView): table = tables.RIRTable +@register_model_view(RIR) class RIRView(generic.ObjectView): queryset = RIR.objects.all() @@ -172,11 +179,13 @@ class RIRView(generic.ObjectView): } +@register_model_view(RIR, 'edit') class RIREditView(generic.ObjectEditView): queryset = RIR.objects.all() form = forms.RIRForm +@register_model_view(RIR, 'delete') class RIRDeleteView(generic.ObjectDeleteView): queryset = RIR.objects.all() @@ -218,6 +227,7 @@ class ASNListView(generic.ObjectListView): table = tables.ASNTable +@register_model_view(ASN) class ASNView(generic.ObjectView): queryset = ASN.objects.all() @@ -242,11 +252,13 @@ class ASNView(generic.ObjectView): } +@register_model_view(ASN, 'edit') class ASNEditView(generic.ObjectEditView): queryset = ASN.objects.all() form = forms.ASNForm +@register_model_view(ASN, 'delete') class ASNDeleteView(generic.ObjectDeleteView): queryset = ASN.objects.all() @@ -287,6 +299,7 @@ class AggregateListView(generic.ObjectListView): table = tables.AggregateTable +@register_model_view(Aggregate) class AggregateView(generic.ObjectView): queryset = Aggregate.objects.all() @@ -325,11 +338,13 @@ class AggregatePrefixesView(generic.ObjectChildrenView): } +@register_model_view(Aggregate, 'edit') class AggregateEditView(generic.ObjectEditView): queryset = Aggregate.objects.all() form = forms.AggregateForm +@register_model_view(Aggregate, 'delete') class AggregateDeleteView(generic.ObjectDeleteView): queryset = Aggregate.objects.all() @@ -372,6 +387,7 @@ class RoleListView(generic.ObjectListView): table = tables.RoleTable +@register_model_view(Role) class RoleView(generic.ObjectView): queryset = Role.objects.all() @@ -388,11 +404,13 @@ class RoleView(generic.ObjectView): } +@register_model_view(Role, 'edit') class RoleEditView(generic.ObjectEditView): queryset = Role.objects.all() form = forms.RoleForm +@register_model_view(Role, 'delete') class RoleDeleteView(generic.ObjectDeleteView): queryset = Role.objects.all() @@ -427,6 +445,7 @@ class PrefixListView(generic.ObjectListView): template_name = 'ipam/prefix_list.html' +@register_model_view(Prefix) class PrefixView(generic.ObjectView): queryset = Prefix.objects.all() @@ -560,11 +579,13 @@ class PrefixIPAddressesView(generic.ObjectChildrenView): } +@register_model_view(Prefix, 'edit') class PrefixEditView(generic.ObjectEditView): queryset = Prefix.objects.all() form = forms.PrefixForm +@register_model_view(Prefix, 'delete') class PrefixDeleteView(generic.ObjectDeleteView): queryset = Prefix.objects.all() @@ -599,6 +620,7 @@ class IPRangeListView(generic.ObjectListView): table = tables.IPRangeTable +@register_model_view(IPRange) class IPRangeView(generic.ObjectView): queryset = IPRange.objects.all() @@ -620,11 +642,13 @@ class IPRangeIPAddressesView(generic.ObjectChildrenView): return parent.get_child_ips().restrict(request.user, 'view') +@register_model_view(IPRange, 'edit') class IPRangeEditView(generic.ObjectEditView): queryset = IPRange.objects.all() form = forms.IPRangeForm +@register_model_view(IPRange, 'delete') class IPRangeDeleteView(generic.ObjectDeleteView): queryset = IPRange.objects.all() @@ -659,6 +683,7 @@ class IPAddressListView(generic.ObjectListView): table = tables.IPAddressTable +@register_model_view(IPAddress) class IPAddressView(generic.ObjectView): queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant') @@ -726,6 +751,7 @@ class IPAddressView(generic.ObjectView): } +@register_model_view(IPAddress, 'edit') class IPAddressEditView(generic.ObjectEditView): queryset = IPAddress.objects.all() form = forms.IPAddressForm @@ -795,6 +821,7 @@ class IPAddressAssignView(generic.ObjectView): }) +@register_model_view(IPAddress, 'delete') class IPAddressDeleteView(generic.ObjectDeleteView): queryset = IPAddress.objects.all() @@ -839,6 +866,7 @@ class VLANGroupListView(generic.ObjectListView): table = tables.VLANGroupTable +@register_model_view(VLANGroup) class VLANGroupView(generic.ObjectView): queryset = VLANGroup.objects.all() @@ -869,11 +897,13 @@ class VLANGroupView(generic.ObjectView): } +@register_model_view(VLANGroup, 'edit') class VLANGroupEditView(generic.ObjectEditView): queryset = VLANGroup.objects.all() form = forms.VLANGroupForm +@register_model_view(VLANGroup, 'delete') class VLANGroupDeleteView(generic.ObjectDeleteView): queryset = VLANGroup.objects.all() @@ -914,6 +944,7 @@ class FHRPGroupListView(generic.ObjectListView): table = tables.FHRPGroupTable +@register_model_view(FHRPGroup) class FHRPGroupView(generic.ObjectView): queryset = FHRPGroup.objects.all() @@ -938,6 +969,7 @@ class FHRPGroupView(generic.ObjectView): } +@register_model_view(FHRPGroup, 'edit') class FHRPGroupEditView(generic.ObjectEditView): queryset = FHRPGroup.objects.all() form = forms.FHRPGroupForm @@ -954,6 +986,7 @@ class FHRPGroupEditView(generic.ObjectEditView): return return_url +@register_model_view(FHRPGroup, 'delete') class FHRPGroupDeleteView(generic.ObjectDeleteView): queryset = FHRPGroup.objects.all() @@ -981,6 +1014,7 @@ class FHRPGroupBulkDeleteView(generic.BulkDeleteView): # FHRP group assignments # +@register_model_view(FHRPGroupAssignment, 'edit') class FHRPGroupAssignmentEditView(generic.ObjectEditView): queryset = FHRPGroupAssignment.objects.all() form = forms.FHRPGroupAssignmentForm @@ -994,6 +1028,7 @@ class FHRPGroupAssignmentEditView(generic.ObjectEditView): return instance +@register_model_view(FHRPGroupAssignment, 'delete') class FHRPGroupAssignmentDeleteView(generic.ObjectDeleteView): queryset = FHRPGroupAssignment.objects.all() @@ -1009,6 +1044,7 @@ class VLANListView(generic.ObjectListView): table = tables.VLANTable +@register_model_view(VLAN) class VLANView(generic.ObjectView): queryset = VLAN.objects.all() @@ -1057,12 +1093,14 @@ class VLANVMInterfacesView(generic.ObjectChildrenView): return parent.get_vminterfaces().restrict(request.user, 'view') +@register_model_view(VLAN, 'edit') class VLANEditView(generic.ObjectEditView): queryset = VLAN.objects.all() form = forms.VLANForm template_name = 'ipam/vlan_edit.html' +@register_model_view(VLAN, 'delete') class VLANDeleteView(generic.ObjectDeleteView): queryset = VLAN.objects.all() @@ -1097,15 +1135,18 @@ class ServiceTemplateListView(generic.ObjectListView): table = tables.ServiceTemplateTable +@register_model_view(ServiceTemplate) class ServiceTemplateView(generic.ObjectView): queryset = ServiceTemplate.objects.all() +@register_model_view(ServiceTemplate, 'edit') class ServiceTemplateEditView(generic.ObjectEditView): queryset = ServiceTemplate.objects.all() form = forms.ServiceTemplateForm +@register_model_view(ServiceTemplate, 'delete') class ServiceTemplateDeleteView(generic.ObjectDeleteView): queryset = ServiceTemplate.objects.all() @@ -1140,6 +1181,7 @@ class ServiceListView(generic.ObjectListView): table = tables.ServiceTable +@register_model_view(Service) class ServiceView(generic.ObjectView): queryset = Service.objects.all() @@ -1150,12 +1192,14 @@ class ServiceCreateView(generic.ObjectEditView): template_name = 'ipam/service_create.html' +@register_model_view(Service, 'edit') class ServiceEditView(generic.ObjectEditView): queryset = Service.objects.all() form = forms.ServiceForm template_name = 'ipam/service_edit.html' +@register_model_view(Service, 'delete') class ServiceDeleteView(generic.ObjectDeleteView): queryset = Service.objects.all() @@ -1181,7 +1225,6 @@ class ServiceBulkDeleteView(generic.BulkDeleteView): # L2VPN - class L2VPNListView(generic.ObjectListView): queryset = L2VPN.objects.all() table = L2VPNTable @@ -1189,6 +1232,7 @@ class L2VPNListView(generic.ObjectListView): filterset_form = forms.L2VPNFilterForm +@register_model_view(L2VPN) class L2VPNView(generic.ObjectView): queryset = L2VPN.objects.all() @@ -1213,11 +1257,13 @@ class L2VPNView(generic.ObjectView): } +@register_model_view(L2VPN, 'edit') class L2VPNEditView(generic.ObjectEditView): queryset = L2VPN.objects.all() form = forms.L2VPNForm +@register_model_view(L2VPN, 'delete') class L2VPNDeleteView(generic.ObjectDeleteView): queryset = L2VPN.objects.all() @@ -1241,6 +1287,10 @@ class L2VPNBulkDeleteView(generic.BulkDeleteView): table = tables.L2VPNTable +# +# L2VPN terminations +# + class L2VPNTerminationListView(generic.ObjectListView): queryset = L2VPNTermination.objects.all() table = L2VPNTerminationTable @@ -1248,16 +1298,19 @@ class L2VPNTerminationListView(generic.ObjectListView): filterset_form = forms.L2VPNTerminationFilterForm +@register_model_view(L2VPNTermination) class L2VPNTerminationView(generic.ObjectView): queryset = L2VPNTermination.objects.all() +@register_model_view(L2VPNTermination, 'edit') class L2VPNTerminationEditView(generic.ObjectEditView): queryset = L2VPNTermination.objects.all() form = forms.L2VPNTerminationForm template_name = 'ipam/l2vpntermination_edit.html' +@register_model_view(L2VPNTermination, 'delete') class L2VPNTerminationDeleteView(generic.ObjectDeleteView): queryset = L2VPNTermination.objects.all() diff --git a/netbox/tenancy/urls.py b/netbox/tenancy/urls.py index b55e949dd..3b5addaec 100644 --- a/netbox/tenancy/urls.py +++ b/netbox/tenancy/urls.py @@ -12,9 +12,6 @@ urlpatterns = [ path('tenant-groups/import/', views.TenantGroupBulkImportView.as_view(), name='tenantgroup_import'), path('tenant-groups/edit/', views.TenantGroupBulkEditView.as_view(), name='tenantgroup_bulk_edit'), path('tenant-groups/delete/', views.TenantGroupBulkDeleteView.as_view(), name='tenantgroup_bulk_delete'), - path('tenant-groups//', views.TenantGroupView.as_view(), name='tenantgroup'), - path('tenant-groups//edit/', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'), - path('tenant-groups//delete/', views.TenantGroupDeleteView.as_view(), name='tenantgroup_delete'), path('tenant-groups//', include(get_model_urls('tenancy', 'tenantgroup'))), # Tenants @@ -23,9 +20,6 @@ urlpatterns = [ path('tenants/import/', views.TenantBulkImportView.as_view(), name='tenant_import'), path('tenants/edit/', views.TenantBulkEditView.as_view(), name='tenant_bulk_edit'), path('tenants/delete/', views.TenantBulkDeleteView.as_view(), name='tenant_bulk_delete'), - path('tenants//', views.TenantView.as_view(), name='tenant'), - path('tenants//edit/', views.TenantEditView.as_view(), name='tenant_edit'), - path('tenants//delete/', views.TenantDeleteView.as_view(), name='tenant_delete'), path('tenants//', include(get_model_urls('tenancy', 'tenant'))), # Contact groups @@ -34,9 +28,6 @@ urlpatterns = [ path('contact-groups/import/', views.ContactGroupBulkImportView.as_view(), name='contactgroup_import'), path('contact-groups/edit/', views.ContactGroupBulkEditView.as_view(), name='contactgroup_bulk_edit'), path('contact-groups/delete/', views.ContactGroupBulkDeleteView.as_view(), name='contactgroup_bulk_delete'), - path('contact-groups//', views.ContactGroupView.as_view(), name='contactgroup'), - path('contact-groups//edit/', views.ContactGroupEditView.as_view(), name='contactgroup_edit'), - path('contact-groups//delete/', views.ContactGroupDeleteView.as_view(), name='contactgroup_delete'), path('contact-groups//', include(get_model_urls('tenancy', 'contactgroup'))), # Contact roles @@ -45,9 +36,6 @@ urlpatterns = [ path('contact-roles/import/', views.ContactRoleBulkImportView.as_view(), name='contactrole_import'), path('contact-roles/edit/', views.ContactRoleBulkEditView.as_view(), name='contactrole_bulk_edit'), path('contact-roles/delete/', views.ContactRoleBulkDeleteView.as_view(), name='contactrole_bulk_delete'), - path('contact-roles//', views.ContactRoleView.as_view(), name='contactrole'), - path('contact-roles//edit/', views.ContactRoleEditView.as_view(), name='contactrole_edit'), - path('contact-roles//delete/', views.ContactRoleDeleteView.as_view(), name='contactrole_delete'), path('contact-roles//', include(get_model_urls('tenancy', 'contactrole'))), # Contacts @@ -56,14 +44,10 @@ urlpatterns = [ path('contacts/import/', views.ContactBulkImportView.as_view(), name='contact_import'), path('contacts/edit/', views.ContactBulkEditView.as_view(), name='contact_bulk_edit'), path('contacts/delete/', views.ContactBulkDeleteView.as_view(), name='contact_bulk_delete'), - path('contacts//', views.ContactView.as_view(), name='contact'), - path('contacts//edit/', views.ContactEditView.as_view(), name='contact_edit'), - path('contacts//delete/', views.ContactDeleteView.as_view(), name='contact_delete'), path('contacts//', include(get_model_urls('tenancy', 'contact'))), # Contact assignments path('contact-assignments/add/', views.ContactAssignmentEditView.as_view(), name='contactassignment_add'), - path('contact-assignments//edit/', views.ContactAssignmentEditView.as_view(), name='contactassignment_edit'), - path('contact-assignments//delete/', views.ContactAssignmentDeleteView.as_view(), name='contactassignment_delete'), + path('contact-assignments//', include(get_model_urls('tenancy', 'contactassignment'))), ] diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index e582c15d1..1ebbda208 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -1,5 +1,4 @@ from django.contrib.contenttypes.models import ContentType -from django.http import QueryDict from django.shortcuts import get_object_or_404 from circuits.models import Circuit @@ -7,6 +6,7 @@ from dcim.models import Cable, Device, Location, Rack, RackReservation, Site from ipam.models import Aggregate, IPAddress, IPRange, Prefix, VLAN, VRF, ASN from netbox.views import generic from utilities.utils import count_related +from utilities.views import register_model_view from virtualization.models import VirtualMachine, Cluster from wireless.models import WirelessLAN, WirelessLink from . import filtersets, forms, tables @@ -30,6 +30,7 @@ class TenantGroupListView(generic.ObjectListView): table = tables.TenantGroupTable +@register_model_view(TenantGroup) class TenantGroupView(generic.ObjectView): queryset = TenantGroup.objects.all() @@ -45,11 +46,13 @@ class TenantGroupView(generic.ObjectView): } +@register_model_view(TenantGroup, 'edit') class TenantGroupEditView(generic.ObjectEditView): queryset = TenantGroup.objects.all() form = forms.TenantGroupForm +@register_model_view(TenantGroup, 'delete') class TenantGroupDeleteView(generic.ObjectDeleteView): queryset = TenantGroup.objects.all() @@ -95,6 +98,7 @@ class TenantListView(generic.ObjectListView): table = tables.TenantTable +@register_model_view(Tenant) class TenantView(generic.ObjectView): queryset = Tenant.objects.all() @@ -125,11 +129,13 @@ class TenantView(generic.ObjectView): } +@register_model_view(Tenant, 'edit') class TenantEditView(generic.ObjectEditView): queryset = Tenant.objects.all() form = forms.TenantForm +@register_model_view(Tenant, 'delete') class TenantDeleteView(generic.ObjectDeleteView): queryset = Tenant.objects.all() @@ -170,6 +176,7 @@ class ContactGroupListView(generic.ObjectListView): table = tables.ContactGroupTable +@register_model_view(ContactGroup) class ContactGroupView(generic.ObjectView): queryset = ContactGroup.objects.all() @@ -198,11 +205,13 @@ class ContactGroupView(generic.ObjectView): } +@register_model_view(ContactGroup, 'edit') class ContactGroupEditView(generic.ObjectEditView): queryset = ContactGroup.objects.all() form = forms.ContactGroupForm +@register_model_view(ContactGroup, 'delete') class ContactGroupDeleteView(generic.ObjectDeleteView): queryset = ContactGroup.objects.all() @@ -248,6 +257,7 @@ class ContactRoleListView(generic.ObjectListView): table = tables.ContactRoleTable +@register_model_view(ContactRole) class ContactRoleView(generic.ObjectView): queryset = ContactRole.objects.all() @@ -265,11 +275,13 @@ class ContactRoleView(generic.ObjectView): } +@register_model_view(ContactRole, 'edit') class ContactRoleEditView(generic.ObjectEditView): queryset = ContactRole.objects.all() form = forms.ContactRoleForm +@register_model_view(ContactRole, 'delete') class ContactRoleDeleteView(generic.ObjectDeleteView): queryset = ContactRole.objects.all() @@ -305,6 +317,7 @@ class ContactListView(generic.ObjectListView): table = tables.ContactTable +@register_model_view(Contact) class ContactView(generic.ObjectView): queryset = Contact.objects.all() @@ -322,11 +335,13 @@ class ContactView(generic.ObjectView): } +@register_model_view(Contact, 'edit') class ContactEditView(generic.ObjectEditView): queryset = Contact.objects.all() form = forms.ContactForm +@register_model_view(Contact, 'delete') class ContactDeleteView(generic.ObjectDeleteView): queryset = Contact.objects.all() @@ -354,6 +369,7 @@ class ContactBulkDeleteView(generic.BulkDeleteView): # Contact assignments # +@register_model_view(ContactAssignment, 'edit') class ContactAssignmentEditView(generic.ObjectEditView): queryset = ContactAssignment.objects.all() form = forms.ContactAssignmentForm @@ -373,5 +389,6 @@ class ContactAssignmentEditView(generic.ObjectEditView): } +@register_model_view(ContactAssignment, 'delete') class ContactAssignmentDeleteView(generic.ObjectDeleteView): queryset = ContactAssignment.objects.all() diff --git a/netbox/utilities/urls.py b/netbox/utilities/urls.py index 9ba2a65e6..16642f589 100644 --- a/netbox/utilities/urls.py +++ b/netbox/utilities/urls.py @@ -32,8 +32,10 @@ def get_model_urls(app_label, model_name): view_ = view_.as_view() # Create a path to the view + name = f"{model_name}_{config['name']}" if config['name'] else model_name + url_path = f"{config['path']}/" if config['path'] else '' paths.append( - path(f"{config['path']}/", view_, name=f"{model_name}_{config['name']}", kwargs=config['kwargs']) + path(url_path, view_, name=name, kwargs=config['kwargs']) ) return paths diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index 75c5aecff..bdd6e4880 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -167,7 +167,7 @@ class ViewTab: return self.badge -def register_model_view(model, name, path=None, kwargs=None): +def register_model_view(model, name='', path=None, kwargs=None): """ This decorator can be used to "attach" a view to any model in NetBox. This is typically used to inject additional tabs within a model's detail view. For example, to add a custom tab to NetBox's dcim.Site model: @@ -182,7 +182,7 @@ def register_model_view(model, name, path=None, kwargs=None): Args: model: The Django model class with which this view will be associated. name: The string used to form the view's name for URL resolution (e.g. via `reverse()`). This will be appended - to the name of the base view for the model using an underscore. + to the name of the base view for the model using an underscore. If blank, the model name will be used. path: The URL path by which the view can be reached (optional). If not provided, `name` will be used. kwargs: A dictionary of keyword arguments for the view to include when registering its URL path (optional). """ diff --git a/netbox/virtualization/urls.py b/netbox/virtualization/urls.py index 31914bc3b..9e5d5a670 100644 --- a/netbox/virtualization/urls.py +++ b/netbox/virtualization/urls.py @@ -12,9 +12,6 @@ urlpatterns = [ path('cluster-types/import/', views.ClusterTypeBulkImportView.as_view(), name='clustertype_import'), path('cluster-types/edit/', views.ClusterTypeBulkEditView.as_view(), name='clustertype_bulk_edit'), path('cluster-types/delete/', views.ClusterTypeBulkDeleteView.as_view(), name='clustertype_bulk_delete'), - path('cluster-types//', views.ClusterTypeView.as_view(), name='clustertype'), - path('cluster-types//edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'), - path('cluster-types//delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'), path('cluster-types//', include(get_model_urls('virtualization', 'clustertype'))), # Cluster groups @@ -23,9 +20,6 @@ urlpatterns = [ path('cluster-groups/import/', views.ClusterGroupBulkImportView.as_view(), name='clustergroup_import'), path('cluster-groups/edit/', views.ClusterGroupBulkEditView.as_view(), name='clustergroup_bulk_edit'), path('cluster-groups/delete/', views.ClusterGroupBulkDeleteView.as_view(), name='clustergroup_bulk_delete'), - path('cluster-groups//', views.ClusterGroupView.as_view(), name='clustergroup'), - path('cluster-groups//edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'), - path('cluster-groups//delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'), path('cluster-groups//', include(get_model_urls('virtualization', 'clustergroup'))), # Clusters @@ -34,11 +28,6 @@ urlpatterns = [ path('clusters/import/', views.ClusterBulkImportView.as_view(), name='cluster_import'), path('clusters/edit/', views.ClusterBulkEditView.as_view(), name='cluster_bulk_edit'), path('clusters/delete/', views.ClusterBulkDeleteView.as_view(), name='cluster_bulk_delete'), - path('clusters//', views.ClusterView.as_view(), name='cluster'), - path('clusters//edit/', views.ClusterEditView.as_view(), name='cluster_edit'), - path('clusters//delete/', views.ClusterDeleteView.as_view(), name='cluster_delete'), - path('clusters//devices/add/', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'), - path('clusters//devices/remove/', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'), path('clusters//', include(get_model_urls('virtualization', 'cluster'))), # Virtual machines @@ -47,9 +36,6 @@ urlpatterns = [ path('virtual-machines/import/', views.VirtualMachineBulkImportView.as_view(), name='virtualmachine_import'), path('virtual-machines/edit/', views.VirtualMachineBulkEditView.as_view(), name='virtualmachine_bulk_edit'), path('virtual-machines/delete/', views.VirtualMachineBulkDeleteView.as_view(), name='virtualmachine_bulk_delete'), - path('virtual-machines//', views.VirtualMachineView.as_view(), name='virtualmachine'), - path('virtual-machines//edit/', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'), - path('virtual-machines//delete/', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'), path('virtual-machines//', include(get_model_urls('virtualization', 'virtualmachine'))), # VM interfaces @@ -59,9 +45,6 @@ urlpatterns = [ path('interfaces/edit/', views.VMInterfaceBulkEditView.as_view(), name='vminterface_bulk_edit'), path('interfaces/rename/', views.VMInterfaceBulkRenameView.as_view(), name='vminterface_bulk_rename'), path('interfaces/delete/', views.VMInterfaceBulkDeleteView.as_view(), name='vminterface_bulk_delete'), - path('interfaces//', views.VMInterfaceView.as_view(), name='vminterface'), - path('interfaces//edit/', views.VMInterfaceEditView.as_view(), name='vminterface_edit'), - path('interfaces//delete/', views.VMInterfaceDeleteView.as_view(), name='vminterface_delete'), path('interfaces//', include(get_model_urls('virtualization', 'vminterface'))), path('virtual-machines/interfaces/add/', views.VirtualMachineBulkAddInterfaceView.as_view(), name='virtualmachine_bulk_add_vminterface'), diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index 6a4cc32f4..bda2415a5 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -31,6 +31,7 @@ class ClusterTypeListView(generic.ObjectListView): table = tables.ClusterTypeTable +@register_model_view(ClusterType) class ClusterTypeView(generic.ObjectView): queryset = ClusterType.objects.all() @@ -49,11 +50,13 @@ class ClusterTypeView(generic.ObjectView): } +@register_model_view(ClusterType, 'edit') class ClusterTypeEditView(generic.ObjectEditView): queryset = ClusterType.objects.all() form = forms.ClusterTypeForm +@register_model_view(ClusterType, 'delete') class ClusterTypeDeleteView(generic.ObjectDeleteView): queryset = ClusterType.objects.all() @@ -93,6 +96,7 @@ class ClusterGroupListView(generic.ObjectListView): table = tables.ClusterGroupTable +@register_model_view(ClusterGroup) class ClusterGroupView(generic.ObjectView): queryset = ClusterGroup.objects.all() @@ -111,11 +115,13 @@ class ClusterGroupView(generic.ObjectView): } +@register_model_view(ClusterGroup, 'edit') class ClusterGroupEditView(generic.ObjectEditView): queryset = ClusterGroup.objects.all() form = forms.ClusterGroupForm +@register_model_view(ClusterGroup, 'delete') class ClusterGroupDeleteView(generic.ObjectDeleteView): queryset = ClusterGroup.objects.all() @@ -159,6 +165,7 @@ class ClusterListView(generic.ObjectListView): filterset_form = forms.ClusterFilterForm +@register_model_view(Cluster) class ClusterView(generic.ObjectView): queryset = Cluster.objects.all() @@ -197,11 +204,13 @@ class ClusterDevicesView(generic.ObjectChildrenView): return Device.objects.restrict(request.user, 'view').filter(cluster=parent) +@register_model_view(Cluster, 'edit') class ClusterEditView(generic.ObjectEditView): queryset = Cluster.objects.all() form = forms.ClusterForm +@register_model_view(Cluster, 'delete') class ClusterDeleteView(generic.ObjectDeleteView): queryset = Cluster.objects.all() @@ -225,6 +234,7 @@ class ClusterBulkDeleteView(generic.BulkDeleteView): table = tables.ClusterTable +@register_model_view(Cluster, 'add_devices', path='devices/add') class ClusterAddDevicesView(generic.ObjectEditView): queryset = Cluster.objects.all() form = forms.ClusterAddDevicesForm @@ -266,6 +276,7 @@ class ClusterAddDevicesView(generic.ObjectEditView): }) +@register_model_view(Cluster, 'remove_devices', path='devices/remove') class ClusterRemoveDevicesView(generic.ObjectEditView): queryset = Cluster.objects.all() form = forms.ClusterRemoveDevicesForm @@ -319,6 +330,7 @@ class VirtualMachineListView(generic.ObjectListView): template_name = 'virtualization/virtualmachine_list.html' +@register_model_view(VirtualMachine) class VirtualMachineView(generic.ObjectView): queryset = VirtualMachine.objects.prefetch_related('tenant__group') @@ -378,11 +390,13 @@ class VirtualMachineConfigContextView(ObjectConfigContextView): ) +@register_model_view(VirtualMachine, 'edit') class VirtualMachineEditView(generic.ObjectEditView): queryset = VirtualMachine.objects.all() form = forms.VirtualMachineForm +@register_model_view(VirtualMachine, 'delete') class VirtualMachineDeleteView(generic.ObjectDeleteView): queryset = VirtualMachine.objects.all() @@ -418,6 +432,7 @@ class VMInterfaceListView(generic.ObjectListView): actions = ('import', 'export', 'bulk_edit', 'bulk_delete') +@register_model_view(VMInterface) class VMInterfaceView(generic.ObjectView): queryset = VMInterface.objects.all() @@ -463,11 +478,13 @@ class VMInterfaceCreateView(generic.ComponentCreateView): model_form = forms.VMInterfaceForm +@register_model_view(VMInterface, 'edit') class VMInterfaceEditView(generic.ObjectEditView): queryset = VMInterface.objects.all() form = forms.VMInterfaceForm +@register_model_view(VMInterface, 'delete') class VMInterfaceDeleteView(generic.ObjectDeleteView): queryset = VMInterface.objects.all() diff --git a/netbox/wireless/urls.py b/netbox/wireless/urls.py index d6e84b1b8..cf8ea5716 100644 --- a/netbox/wireless/urls.py +++ b/netbox/wireless/urls.py @@ -12,9 +12,6 @@ urlpatterns = ( path('wireless-lan-groups/import/', views.WirelessLANGroupBulkImportView.as_view(), name='wirelesslangroup_import'), path('wireless-lan-groups/edit/', views.WirelessLANGroupBulkEditView.as_view(), name='wirelesslangroup_bulk_edit'), path('wireless-lan-groups/delete/', views.WirelessLANGroupBulkDeleteView.as_view(), name='wirelesslangroup_bulk_delete'), - path('wireless-lan-groups//', views.WirelessLANGroupView.as_view(), name='wirelesslangroup'), - path('wireless-lan-groups//edit/', views.WirelessLANGroupEditView.as_view(), name='wirelesslangroup_edit'), - path('wireless-lan-groups//delete/', views.WirelessLANGroupDeleteView.as_view(), name='wirelesslangroup_delete'), path('wireless-lan-groups//', include(get_model_urls('wireless', 'wirelesslangroup'))), # Wireless LANs @@ -23,9 +20,6 @@ urlpatterns = ( path('wireless-lans/import/', views.WirelessLANBulkImportView.as_view(), name='wirelesslan_import'), path('wireless-lans/edit/', views.WirelessLANBulkEditView.as_view(), name='wirelesslan_bulk_edit'), path('wireless-lans/delete/', views.WirelessLANBulkDeleteView.as_view(), name='wirelesslan_bulk_delete'), - path('wireless-lans//', views.WirelessLANView.as_view(), name='wirelesslan'), - path('wireless-lans//edit/', views.WirelessLANEditView.as_view(), name='wirelesslan_edit'), - path('wireless-lans//delete/', views.WirelessLANDeleteView.as_view(), name='wirelesslan_delete'), path('wireless-lans//', include(get_model_urls('wireless', 'wirelesslan'))), # Wireless links @@ -34,9 +28,6 @@ urlpatterns = ( path('wireless-links/import/', views.WirelessLinkBulkImportView.as_view(), name='wirelesslink_import'), path('wireless-links/edit/', views.WirelessLinkBulkEditView.as_view(), name='wirelesslink_bulk_edit'), path('wireless-links/delete/', views.WirelessLinkBulkDeleteView.as_view(), name='wirelesslink_bulk_delete'), - path('wireless-links//', views.WirelessLinkView.as_view(), name='wirelesslink'), - path('wireless-links//edit/', views.WirelessLinkEditView.as_view(), name='wirelesslink_edit'), - path('wireless-links//delete/', views.WirelessLinkDeleteView.as_view(), name='wirelesslink_delete'), path('wireless-links//', include(get_model_urls('wireless', 'wirelesslink'))), ) diff --git a/netbox/wireless/views.py b/netbox/wireless/views.py index 988aa1b6d..e4e7617ed 100644 --- a/netbox/wireless/views.py +++ b/netbox/wireless/views.py @@ -1,6 +1,7 @@ from dcim.models import Interface from netbox.views import generic from utilities.utils import count_related +from utilities.views import register_model_view from . import filtersets, forms, tables from .models import * @@ -22,6 +23,7 @@ class WirelessLANGroupListView(generic.ObjectListView): table = tables.WirelessLANGroupTable +@register_model_view(WirelessLANGroup) class WirelessLANGroupView(generic.ObjectView): queryset = WirelessLANGroup.objects.all() @@ -37,11 +39,13 @@ class WirelessLANGroupView(generic.ObjectView): } +@register_model_view(WirelessLANGroup, 'edit') class WirelessLANGroupEditView(generic.ObjectEditView): queryset = WirelessLANGroup.objects.all() form = forms.WirelessLANGroupForm +@register_model_view(WirelessLANGroup, 'delete') class WirelessLANGroupDeleteView(generic.ObjectDeleteView): queryset = WirelessLANGroup.objects.all() @@ -90,6 +94,7 @@ class WirelessLANListView(generic.ObjectListView): table = tables.WirelessLANTable +@register_model_view(WirelessLAN) class WirelessLANView(generic.ObjectView): queryset = WirelessLAN.objects.all() @@ -105,11 +110,13 @@ class WirelessLANView(generic.ObjectView): } +@register_model_view(WirelessLAN, 'edit') class WirelessLANEditView(generic.ObjectEditView): queryset = WirelessLAN.objects.all() form = forms.WirelessLANForm +@register_model_view(WirelessLAN, 'delete') class WirelessLANDeleteView(generic.ObjectDeleteView): queryset = WirelessLAN.objects.all() @@ -144,15 +151,18 @@ class WirelessLinkListView(generic.ObjectListView): table = tables.WirelessLinkTable +@register_model_view(WirelessLink) class WirelessLinkView(generic.ObjectView): queryset = WirelessLink.objects.all() +@register_model_view(WirelessLink, 'edit') class WirelessLinkEditView(generic.ObjectEditView): queryset = WirelessLink.objects.all() form = forms.WirelessLinkForm +@register_model_view(WirelessLink, 'delete') class WirelessLinkDeleteView(generic.ObjectDeleteView): queryset = WirelessLink.objects.all()