Преглед изворни кода

Replace static journaling, changelog URL paths with dynamic resolution

jeremystretch пре 3 година
родитељ
комит
a0bae06ff7
7 измењених фајлова са 90 додато и 131 уклоњено
  1. 7 10
      netbox/circuits/urls.py
  2. 35 44
      netbox/dcim/urls.py
  3. 10 17
      netbox/extras/urls.py
  4. 19 32
      netbox/ipam/urls.py
  5. 7 10
      netbox/tenancy/urls.py
  6. 7 10
      netbox/virtualization/urls.py
  7. 5 8
      netbox/wireless/urls.py

+ 7 - 10
netbox/circuits/urls.py

@@ -1,9 +1,9 @@
-from django.urls import path
+from django.urls import include, path
 
 
 from dcim.views import PathTraceView
 from dcim.views import PathTraceView
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import *
+from .models import CircuitTermination
 
 
 app_name = 'circuits'
 app_name = 'circuits'
 urlpatterns = [
 urlpatterns = [
@@ -17,8 +17,7 @@ urlpatterns = [
     path('providers/<int:pk>/', views.ProviderView.as_view(), name='provider'),
     path('providers/<int:pk>/', views.ProviderView.as_view(), name='provider'),
     path('providers/<int:pk>/edit/', views.ProviderEditView.as_view(), name='provider_edit'),
     path('providers/<int:pk>/edit/', views.ProviderEditView.as_view(), name='provider_edit'),
     path('providers/<int:pk>/delete/', views.ProviderDeleteView.as_view(), name='provider_delete'),
     path('providers/<int:pk>/delete/', views.ProviderDeleteView.as_view(), name='provider_delete'),
-    path('providers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='provider_changelog', kwargs={'model': Provider}),
-    path('providers/<int:pk>/journal/', ObjectJournalView.as_view(), name='provider_journal', kwargs={'model': Provider}),
+    path('providers/<int:pk>/', include(get_model_urls('circuits', 'provider'))),
 
 
     # Provider networks
     # Provider networks
     path('provider-networks/', views.ProviderNetworkListView.as_view(), name='providernetwork_list'),
     path('provider-networks/', views.ProviderNetworkListView.as_view(), name='providernetwork_list'),
@@ -29,8 +28,7 @@ urlpatterns = [
     path('provider-networks/<int:pk>/', views.ProviderNetworkView.as_view(), name='providernetwork'),
     path('provider-networks/<int:pk>/', views.ProviderNetworkView.as_view(), name='providernetwork'),
     path('provider-networks/<int:pk>/edit/', views.ProviderNetworkEditView.as_view(), name='providernetwork_edit'),
     path('provider-networks/<int:pk>/edit/', views.ProviderNetworkEditView.as_view(), name='providernetwork_edit'),
     path('provider-networks/<int:pk>/delete/', views.ProviderNetworkDeleteView.as_view(), name='providernetwork_delete'),
     path('provider-networks/<int:pk>/delete/', views.ProviderNetworkDeleteView.as_view(), name='providernetwork_delete'),
-    path('provider-networks/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='providernetwork_changelog', kwargs={'model': ProviderNetwork}),
-    path('provider-networks/<int:pk>/journal/', ObjectJournalView.as_view(), name='providernetwork_journal', kwargs={'model': ProviderNetwork}),
+    path('provider-networks/<int:pk>/', include(get_model_urls('circuits', 'providernetwork'))),
 
 
     # Circuit types
     # Circuit types
     path('circuit-types/', views.CircuitTypeListView.as_view(), name='circuittype_list'),
     path('circuit-types/', views.CircuitTypeListView.as_view(), name='circuittype_list'),
@@ -41,7 +39,7 @@ urlpatterns = [
     path('circuit-types/<int:pk>/', views.CircuitTypeView.as_view(), name='circuittype'),
     path('circuit-types/<int:pk>/', views.CircuitTypeView.as_view(), name='circuittype'),
     path('circuit-types/<int:pk>/edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
     path('circuit-types/<int:pk>/edit/', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),
     path('circuit-types/<int:pk>/delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'),
     path('circuit-types/<int:pk>/delete/', views.CircuitTypeDeleteView.as_view(), name='circuittype_delete'),
-    path('circuit-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuittype_changelog', kwargs={'model': CircuitType}),
+    path('circuit-types/<int:pk>/', include(get_model_urls('circuits', 'circuittype'))),
 
 
     # Circuits
     # Circuits
     path('circuits/', views.CircuitListView.as_view(), name='circuit_list'),
     path('circuits/', views.CircuitListView.as_view(), name='circuit_list'),
@@ -52,9 +50,8 @@ urlpatterns = [
     path('circuits/<int:pk>/', views.CircuitView.as_view(), name='circuit'),
     path('circuits/<int:pk>/', views.CircuitView.as_view(), name='circuit'),
     path('circuits/<int:pk>/edit/', views.CircuitEditView.as_view(), name='circuit_edit'),
     path('circuits/<int:pk>/edit/', views.CircuitEditView.as_view(), name='circuit_edit'),
     path('circuits/<int:pk>/delete/', views.CircuitDeleteView.as_view(), name='circuit_delete'),
     path('circuits/<int:pk>/delete/', views.CircuitDeleteView.as_view(), name='circuit_delete'),
-    path('circuits/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='circuit_changelog', kwargs={'model': Circuit}),
-    path('circuits/<int:pk>/journal/', ObjectJournalView.as_view(), name='circuit_journal', kwargs={'model': Circuit}),
     path('circuits/<int:pk>/terminations/swap/', views.CircuitSwapTerminations.as_view(), name='circuit_terminations_swap'),
     path('circuits/<int:pk>/terminations/swap/', views.CircuitSwapTerminations.as_view(), name='circuit_terminations_swap'),
+    path('circuits/<int:pk>/', include(get_model_urls('circuits', 'circuit'))),
 
 
     # Circuit terminations
     # Circuit terminations
     path('circuit-terminations/add/', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'),
     path('circuit-terminations/add/', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'),

+ 35 - 44
netbox/dcim/urls.py

@@ -1,8 +1,10 @@
-from django.urls import path
+from django.urls import include, path
 
 
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import *
+from .models import (
+    ConsolePort, ConsoleServerPort, FrontPort, Interface, PowerFeed, PowerPort, PowerOutlet, RearPort,
+)
 
 
 app_name = 'dcim'
 app_name = 'dcim'
 urlpatterns = [
 urlpatterns = [
@@ -16,7 +18,7 @@ urlpatterns = [
     path('regions/<int:pk>/', views.RegionView.as_view(), name='region'),
     path('regions/<int:pk>/', views.RegionView.as_view(), name='region'),
     path('regions/<int:pk>/edit/', views.RegionEditView.as_view(), name='region_edit'),
     path('regions/<int:pk>/edit/', views.RegionEditView.as_view(), name='region_edit'),
     path('regions/<int:pk>/delete/', views.RegionDeleteView.as_view(), name='region_delete'),
     path('regions/<int:pk>/delete/', views.RegionDeleteView.as_view(), name='region_delete'),
-    path('regions/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='region_changelog', kwargs={'model': Region}),
+    path('regions/<int:pk>/', include(get_model_urls('dcim', 'region'))),
 
 
     # Site groups
     # Site groups
     path('site-groups/', views.SiteGroupListView.as_view(), name='sitegroup_list'),
     path('site-groups/', views.SiteGroupListView.as_view(), name='sitegroup_list'),
@@ -27,7 +29,7 @@ urlpatterns = [
     path('site-groups/<int:pk>/', views.SiteGroupView.as_view(), name='sitegroup'),
     path('site-groups/<int:pk>/', views.SiteGroupView.as_view(), name='sitegroup'),
     path('site-groups/<int:pk>/edit/', views.SiteGroupEditView.as_view(), name='sitegroup_edit'),
     path('site-groups/<int:pk>/edit/', views.SiteGroupEditView.as_view(), name='sitegroup_edit'),
     path('site-groups/<int:pk>/delete/', views.SiteGroupDeleteView.as_view(), name='sitegroup_delete'),
     path('site-groups/<int:pk>/delete/', views.SiteGroupDeleteView.as_view(), name='sitegroup_delete'),
-    path('site-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='sitegroup_changelog', kwargs={'model': SiteGroup}),
+    path('site-groups/<int:pk>/', include(get_model_urls('dcim', 'sitegroup'))),
 
 
     # Sites
     # Sites
     path('sites/', views.SiteListView.as_view(), name='site_list'),
     path('sites/', views.SiteListView.as_view(), name='site_list'),
@@ -38,8 +40,7 @@ urlpatterns = [
     path('sites/<int:pk>/', views.SiteView.as_view(), name='site'),
     path('sites/<int:pk>/', views.SiteView.as_view(), name='site'),
     path('sites/<int:pk>/edit/', views.SiteEditView.as_view(), name='site_edit'),
     path('sites/<int:pk>/edit/', views.SiteEditView.as_view(), name='site_edit'),
     path('sites/<int:pk>/delete/', views.SiteDeleteView.as_view(), name='site_delete'),
     path('sites/<int:pk>/delete/', views.SiteDeleteView.as_view(), name='site_delete'),
-    path('sites/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='site_changelog', kwargs={'model': Site}),
-    path('sites/<int:pk>/journal/', ObjectJournalView.as_view(), name='site_journal', kwargs={'model': Site}),
+    path('sites/<int:pk>/', include(get_model_urls('dcim', 'site'))),
 
 
     # Locations
     # Locations
     path('locations/', views.LocationListView.as_view(), name='location_list'),
     path('locations/', views.LocationListView.as_view(), name='location_list'),
@@ -50,7 +51,7 @@ urlpatterns = [
     path('locations/<int:pk>/', views.LocationView.as_view(), name='location'),
     path('locations/<int:pk>/', views.LocationView.as_view(), name='location'),
     path('locations/<int:pk>/edit/', views.LocationEditView.as_view(), name='location_edit'),
     path('locations/<int:pk>/edit/', views.LocationEditView.as_view(), name='location_edit'),
     path('locations/<int:pk>/delete/', views.LocationDeleteView.as_view(), name='location_delete'),
     path('locations/<int:pk>/delete/', views.LocationDeleteView.as_view(), name='location_delete'),
-    path('locations/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='location_changelog', kwargs={'model': Location}),
+    path('locations/<int:pk>/', include(get_model_urls('dcim', 'location'))),
 
 
     # Rack roles
     # Rack roles
     path('rack-roles/', views.RackRoleListView.as_view(), name='rackrole_list'),
     path('rack-roles/', views.RackRoleListView.as_view(), name='rackrole_list'),
@@ -61,7 +62,7 @@ urlpatterns = [
     path('rack-roles/<int:pk>/', views.RackRoleView.as_view(), name='rackrole'),
     path('rack-roles/<int:pk>/', views.RackRoleView.as_view(), name='rackrole'),
     path('rack-roles/<int:pk>/edit/', views.RackRoleEditView.as_view(), name='rackrole_edit'),
     path('rack-roles/<int:pk>/edit/', views.RackRoleEditView.as_view(), name='rackrole_edit'),
     path('rack-roles/<int:pk>/delete/', views.RackRoleDeleteView.as_view(), name='rackrole_delete'),
     path('rack-roles/<int:pk>/delete/', views.RackRoleDeleteView.as_view(), name='rackrole_delete'),
-    path('rack-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rackrole_changelog', kwargs={'model': RackRole}),
+    path('rack-roles/<int:pk>/', include(get_model_urls('dcim', 'rackrole'))),
 
 
     # Rack reservations
     # Rack reservations
     path('rack-reservations/', views.RackReservationListView.as_view(), name='rackreservation_list'),
     path('rack-reservations/', views.RackReservationListView.as_view(), name='rackreservation_list'),
@@ -72,8 +73,7 @@ urlpatterns = [
     path('rack-reservations/<int:pk>/', views.RackReservationView.as_view(), name='rackreservation'),
     path('rack-reservations/<int:pk>/', views.RackReservationView.as_view(), name='rackreservation'),
     path('rack-reservations/<int:pk>/edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
     path('rack-reservations/<int:pk>/edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
     path('rack-reservations/<int:pk>/delete/', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
     path('rack-reservations/<int:pk>/delete/', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
-    path('rack-reservations/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rackreservation_changelog', kwargs={'model': RackReservation}),
-    path('rack-reservations/<int:pk>/journal/', ObjectJournalView.as_view(), name='rackreservation_journal', kwargs={'model': RackReservation}),
+    path('rack-reservations/<int:pk>/', include(get_model_urls('dcim', 'rackreservation'))),
 
 
     # Racks
     # Racks
     path('racks/', views.RackListView.as_view(), name='rack_list'),
     path('racks/', views.RackListView.as_view(), name='rack_list'),
@@ -85,8 +85,7 @@ urlpatterns = [
     path('racks/<int:pk>/', views.RackView.as_view(), name='rack'),
     path('racks/<int:pk>/', views.RackView.as_view(), name='rack'),
     path('racks/<int:pk>/edit/', views.RackEditView.as_view(), name='rack_edit'),
     path('racks/<int:pk>/edit/', views.RackEditView.as_view(), name='rack_edit'),
     path('racks/<int:pk>/delete/', views.RackDeleteView.as_view(), name='rack_delete'),
     path('racks/<int:pk>/delete/', views.RackDeleteView.as_view(), name='rack_delete'),
-    path('racks/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rack_changelog', kwargs={'model': Rack}),
-    path('racks/<int:pk>/journal/', ObjectJournalView.as_view(), name='rack_journal', kwargs={'model': Rack}),
+    path('racks/<int:pk>/', include(get_model_urls('dcim', 'rack'))),
 
 
     # Manufacturers
     # Manufacturers
     path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),
     path('manufacturers/', views.ManufacturerListView.as_view(), name='manufacturer_list'),
@@ -97,7 +96,7 @@ urlpatterns = [
     path('manufacturers/<int:pk>/', views.ManufacturerView.as_view(), name='manufacturer'),
     path('manufacturers/<int:pk>/', views.ManufacturerView.as_view(), name='manufacturer'),
     path('manufacturers/<int:pk>/edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
     path('manufacturers/<int:pk>/edit/', views.ManufacturerEditView.as_view(), name='manufacturer_edit'),
     path('manufacturers/<int:pk>/delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'),
     path('manufacturers/<int:pk>/delete/', views.ManufacturerDeleteView.as_view(), name='manufacturer_delete'),
-    path('manufacturers/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='manufacturer_changelog', kwargs={'model': Manufacturer}),
+    path('manufacturers/<int:pk>/', include(get_model_urls('dcim', 'manufacturer'))),
 
 
     # Device types
     # Device types
     path('device-types/', views.DeviceTypeListView.as_view(), name='devicetype_list'),
     path('device-types/', views.DeviceTypeListView.as_view(), name='devicetype_list'),
@@ -118,8 +117,7 @@ urlpatterns = [
     path('device-types/<int:pk>/inventory-items/', views.DeviceTypeInventoryItemsView.as_view(), name='devicetype_inventoryitems'),
     path('device-types/<int:pk>/inventory-items/', views.DeviceTypeInventoryItemsView.as_view(), name='devicetype_inventoryitems'),
     path('device-types/<int:pk>/edit/', views.DeviceTypeEditView.as_view(), name='devicetype_edit'),
     path('device-types/<int:pk>/edit/', views.DeviceTypeEditView.as_view(), name='devicetype_edit'),
     path('device-types/<int:pk>/delete/', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'),
     path('device-types/<int:pk>/delete/', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'),
-    path('device-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='devicetype_changelog', kwargs={'model': DeviceType}),
-    path('device-types/<int:pk>/journal/', ObjectJournalView.as_view(), name='devicetype_journal', kwargs={'model': DeviceType}),
+    path('device-types/<int:pk>/', include(get_model_urls('dcim', 'devicetype'))),
 
 
     # Module types
     # Module types
     path('module-types/', views.ModuleTypeListView.as_view(), name='moduletype_list'),
     path('module-types/', views.ModuleTypeListView.as_view(), name='moduletype_list'),
@@ -137,8 +135,7 @@ urlpatterns = [
     path('module-types/<int:pk>/rear-ports/', views.ModuleTypeRearPortsView.as_view(), name='moduletype_rearports'),
     path('module-types/<int:pk>/rear-ports/', views.ModuleTypeRearPortsView.as_view(), name='moduletype_rearports'),
     path('module-types/<int:pk>/edit/', views.ModuleTypeEditView.as_view(), name='moduletype_edit'),
     path('module-types/<int:pk>/edit/', views.ModuleTypeEditView.as_view(), name='moduletype_edit'),
     path('module-types/<int:pk>/delete/', views.ModuleTypeDeleteView.as_view(), name='moduletype_delete'),
     path('module-types/<int:pk>/delete/', views.ModuleTypeDeleteView.as_view(), name='moduletype_delete'),
-    path('module-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='moduletype_changelog', kwargs={'model': ModuleType}),
-    path('module-types/<int:pk>/journal/', ObjectJournalView.as_view(), name='moduletype_journal', kwargs={'model': ModuleType}),
+    path('module-types/<int:pk>/', include(get_model_urls('dcim', 'moduletype'))),
 
 
     # Console port templates
     # Console port templates
     path('console-port-templates/add/', views.ConsolePortTemplateCreateView.as_view(), name='consoleporttemplate_add'),
     path('console-port-templates/add/', views.ConsolePortTemplateCreateView.as_view(), name='consoleporttemplate_add'),
@@ -229,7 +226,7 @@ urlpatterns = [
     path('device-roles/<int:pk>/', views.DeviceRoleView.as_view(), name='devicerole'),
     path('device-roles/<int:pk>/', views.DeviceRoleView.as_view(), name='devicerole'),
     path('device-roles/<int:pk>/edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
     path('device-roles/<int:pk>/edit/', views.DeviceRoleEditView.as_view(), name='devicerole_edit'),
     path('device-roles/<int:pk>/delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'),
     path('device-roles/<int:pk>/delete/', views.DeviceRoleDeleteView.as_view(), name='devicerole_delete'),
-    path('device-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='devicerole_changelog', kwargs={'model': DeviceRole}),
+    path('device-roles/<int:pk>/', include(get_model_urls('dcim', 'devicerole'))),
 
 
     # Platforms
     # Platforms
     path('platforms/', views.PlatformListView.as_view(), name='platform_list'),
     path('platforms/', views.PlatformListView.as_view(), name='platform_list'),
@@ -240,7 +237,7 @@ urlpatterns = [
     path('platforms/<int:pk>/', views.PlatformView.as_view(), name='platform'),
     path('platforms/<int:pk>/', views.PlatformView.as_view(), name='platform'),
     path('platforms/<int:pk>/edit/', views.PlatformEditView.as_view(), name='platform_edit'),
     path('platforms/<int:pk>/edit/', views.PlatformEditView.as_view(), name='platform_edit'),
     path('platforms/<int:pk>/delete/', views.PlatformDeleteView.as_view(), name='platform_delete'),
     path('platforms/<int:pk>/delete/', views.PlatformDeleteView.as_view(), name='platform_delete'),
-    path('platforms/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='platform_changelog', kwargs={'model': Platform}),
+    path('platforms/<int:pk>/', include(get_model_urls('dcim', 'platform'))),
 
 
     # Devices
     # Devices
     path('devices/', views.DeviceListView.as_view(), name='device_list'),
     path('devices/', views.DeviceListView.as_view(), name='device_list'),
@@ -264,11 +261,10 @@ urlpatterns = [
     path('devices/<int:pk>/device-bays/', views.DeviceDeviceBaysView.as_view(), name='device_devicebays'),
     path('devices/<int:pk>/device-bays/', views.DeviceDeviceBaysView.as_view(), name='device_devicebays'),
     path('devices/<int:pk>/inventory/', views.DeviceInventoryView.as_view(), name='device_inventory'),
     path('devices/<int:pk>/inventory/', views.DeviceInventoryView.as_view(), name='device_inventory'),
     path('devices/<int:pk>/config-context/', views.DeviceConfigContextView.as_view(), name='device_configcontext'),
     path('devices/<int:pk>/config-context/', views.DeviceConfigContextView.as_view(), name='device_configcontext'),
-    path('devices/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='device_changelog', kwargs={'model': Device}),
-    path('devices/<int:pk>/journal/', ObjectJournalView.as_view(), name='device_journal', kwargs={'model': Device}),
     path('devices/<int:pk>/status/', views.DeviceStatusView.as_view(), name='device_status'),
     path('devices/<int:pk>/status/', views.DeviceStatusView.as_view(), name='device_status'),
     path('devices/<int:pk>/lldp-neighbors/', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'),
     path('devices/<int:pk>/lldp-neighbors/', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'),
     path('devices/<int:pk>/config/', views.DeviceConfigView.as_view(), name='device_config'),
     path('devices/<int:pk>/config/', views.DeviceConfigView.as_view(), name='device_config'),
+    path('devices/<int:pk>/', include(get_model_urls('dcim', 'device'))),
 
 
     # Modules
     # Modules
     path('modules/', views.ModuleListView.as_view(), name='module_list'),
     path('modules/', views.ModuleListView.as_view(), name='module_list'),
@@ -279,8 +275,7 @@ urlpatterns = [
     path('modules/<int:pk>/', views.ModuleView.as_view(), name='module'),
     path('modules/<int:pk>/', views.ModuleView.as_view(), name='module'),
     path('modules/<int:pk>/edit/', views.ModuleEditView.as_view(), name='module_edit'),
     path('modules/<int:pk>/edit/', views.ModuleEditView.as_view(), name='module_edit'),
     path('modules/<int:pk>/delete/', views.ModuleDeleteView.as_view(), name='module_delete'),
     path('modules/<int:pk>/delete/', views.ModuleDeleteView.as_view(), name='module_delete'),
-    path('modules/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='module_changelog', kwargs={'model': Module}),
-    path('modules/<int:pk>/journal/', ObjectJournalView.as_view(), name='module_journal', kwargs={'model': Module}),
+    path('modules/<int:pk>/', include(get_model_urls('dcim', 'module'))),
 
 
     # Console ports
     # Console ports
     path('console-ports/', views.ConsolePortListView.as_view(), name='consoleport_list'),
     path('console-ports/', views.ConsolePortListView.as_view(), name='consoleport_list'),
@@ -293,8 +288,8 @@ urlpatterns = [
     path('console-ports/<int:pk>/', views.ConsolePortView.as_view(), name='consoleport'),
     path('console-ports/<int:pk>/', views.ConsolePortView.as_view(), name='consoleport'),
     path('console-ports/<int:pk>/edit/', views.ConsolePortEditView.as_view(), name='consoleport_edit'),
     path('console-ports/<int:pk>/edit/', views.ConsolePortEditView.as_view(), name='consoleport_edit'),
     path('console-ports/<int:pk>/delete/', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'),
     path('console-ports/<int:pk>/delete/', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'),
-    path('console-ports/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='consoleport_changelog', kwargs={'model': ConsolePort}),
     path('console-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='consoleport_trace', kwargs={'model': ConsolePort}),
     path('console-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='consoleport_trace', kwargs={'model': ConsolePort}),
+    path('console-ports/<int:pk>/', include(get_model_urls('dcim', 'consoleport'))),
     path('devices/console-ports/add/', views.DeviceBulkAddConsolePortView.as_view(), name='device_bulk_add_consoleport'),
     path('devices/console-ports/add/', views.DeviceBulkAddConsolePortView.as_view(), name='device_bulk_add_consoleport'),
 
 
     # Console server ports
     # Console server ports
@@ -308,8 +303,8 @@ urlpatterns = [
     path('console-server-ports/<int:pk>/', views.ConsoleServerPortView.as_view(), name='consoleserverport'),
     path('console-server-ports/<int:pk>/', views.ConsoleServerPortView.as_view(), name='consoleserverport'),
     path('console-server-ports/<int:pk>/edit/', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'),
     path('console-server-ports/<int:pk>/edit/', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'),
     path('console-server-ports/<int:pk>/delete/', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'),
     path('console-server-ports/<int:pk>/delete/', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'),
-    path('console-server-ports/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='consoleserverport_changelog', kwargs={'model': ConsoleServerPort}),
     path('console-server-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='consoleserverport_trace', kwargs={'model': ConsoleServerPort}),
     path('console-server-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='consoleserverport_trace', kwargs={'model': ConsoleServerPort}),
+    path('console-server-ports/<int:pk>/', include(get_model_urls('dcim', 'consoleserverport'))),
     path('devices/console-server-ports/add/', views.DeviceBulkAddConsoleServerPortView.as_view(), name='device_bulk_add_consoleserverport'),
     path('devices/console-server-ports/add/', views.DeviceBulkAddConsoleServerPortView.as_view(), name='device_bulk_add_consoleserverport'),
 
 
     # Power ports
     # Power ports
@@ -323,8 +318,8 @@ urlpatterns = [
     path('power-ports/<int:pk>/', views.PowerPortView.as_view(), name='powerport'),
     path('power-ports/<int:pk>/', views.PowerPortView.as_view(), name='powerport'),
     path('power-ports/<int:pk>/edit/', views.PowerPortEditView.as_view(), name='powerport_edit'),
     path('power-ports/<int:pk>/edit/', views.PowerPortEditView.as_view(), name='powerport_edit'),
     path('power-ports/<int:pk>/delete/', views.PowerPortDeleteView.as_view(), name='powerport_delete'),
     path('power-ports/<int:pk>/delete/', views.PowerPortDeleteView.as_view(), name='powerport_delete'),
-    path('power-ports/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='powerport_changelog', kwargs={'model': PowerPort}),
     path('power-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='powerport_trace', kwargs={'model': PowerPort}),
     path('power-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='powerport_trace', kwargs={'model': PowerPort}),
+    path('power-ports/<int:pk>/', include(get_model_urls('dcim', 'powerport'))),
     path('devices/power-ports/add/', views.DeviceBulkAddPowerPortView.as_view(), name='device_bulk_add_powerport'),
     path('devices/power-ports/add/', views.DeviceBulkAddPowerPortView.as_view(), name='device_bulk_add_powerport'),
 
 
     # Power outlets
     # Power outlets
@@ -338,8 +333,8 @@ urlpatterns = [
     path('power-outlets/<int:pk>/', views.PowerOutletView.as_view(), name='poweroutlet'),
     path('power-outlets/<int:pk>/', views.PowerOutletView.as_view(), name='poweroutlet'),
     path('power-outlets/<int:pk>/edit/', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'),
     path('power-outlets/<int:pk>/edit/', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'),
     path('power-outlets/<int:pk>/delete/', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'),
     path('power-outlets/<int:pk>/delete/', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'),
-    path('power-outlets/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='poweroutlet_changelog', kwargs={'model': PowerOutlet}),
     path('power-outlets/<int:pk>/trace/', views.PathTraceView.as_view(), name='poweroutlet_trace', kwargs={'model': PowerOutlet}),
     path('power-outlets/<int:pk>/trace/', views.PathTraceView.as_view(), name='poweroutlet_trace', kwargs={'model': PowerOutlet}),
+    path('power-outlets/<int:pk>/', include(get_model_urls('dcim', 'poweroutlet'))),
     path('devices/power-outlets/add/', views.DeviceBulkAddPowerOutletView.as_view(), name='device_bulk_add_poweroutlet'),
     path('devices/power-outlets/add/', views.DeviceBulkAddPowerOutletView.as_view(), name='device_bulk_add_poweroutlet'),
 
 
     # Interfaces
     # Interfaces
@@ -353,8 +348,8 @@ urlpatterns = [
     path('interfaces/<int:pk>/', views.InterfaceView.as_view(), name='interface'),
     path('interfaces/<int:pk>/', views.InterfaceView.as_view(), name='interface'),
     path('interfaces/<int:pk>/edit/', views.InterfaceEditView.as_view(), name='interface_edit'),
     path('interfaces/<int:pk>/edit/', views.InterfaceEditView.as_view(), name='interface_edit'),
     path('interfaces/<int:pk>/delete/', views.InterfaceDeleteView.as_view(), name='interface_delete'),
     path('interfaces/<int:pk>/delete/', views.InterfaceDeleteView.as_view(), name='interface_delete'),
-    path('interfaces/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='interface_changelog', kwargs={'model': Interface}),
     path('interfaces/<int:pk>/trace/', views.PathTraceView.as_view(), name='interface_trace', kwargs={'model': Interface}),
     path('interfaces/<int:pk>/trace/', views.PathTraceView.as_view(), name='interface_trace', kwargs={'model': Interface}),
+    path('interfaces/<int:pk>/', include(get_model_urls('dcim', 'interface'))),
     path('devices/interfaces/add/', views.DeviceBulkAddInterfaceView.as_view(), name='device_bulk_add_interface'),
     path('devices/interfaces/add/', views.DeviceBulkAddInterfaceView.as_view(), name='device_bulk_add_interface'),
 
 
     # Front ports
     # Front ports
@@ -368,8 +363,8 @@ urlpatterns = [
     path('front-ports/<int:pk>/', views.FrontPortView.as_view(), name='frontport'),
     path('front-ports/<int:pk>/', views.FrontPortView.as_view(), name='frontport'),
     path('front-ports/<int:pk>/edit/', views.FrontPortEditView.as_view(), name='frontport_edit'),
     path('front-ports/<int:pk>/edit/', views.FrontPortEditView.as_view(), name='frontport_edit'),
     path('front-ports/<int:pk>/delete/', views.FrontPortDeleteView.as_view(), name='frontport_delete'),
     path('front-ports/<int:pk>/delete/', views.FrontPortDeleteView.as_view(), name='frontport_delete'),
-    path('front-ports/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='frontport_changelog', kwargs={'model': FrontPort}),
     path('front-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='frontport_trace', kwargs={'model': FrontPort}),
     path('front-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='frontport_trace', kwargs={'model': FrontPort}),
+    path('front-ports/<int:pk>/', include(get_model_urls('dcim', 'frontport'))),
     # path('devices/front-ports/add/', views.DeviceBulkAddFrontPortView.as_view(), name='device_bulk_add_frontport'),
     # path('devices/front-ports/add/', views.DeviceBulkAddFrontPortView.as_view(), name='device_bulk_add_frontport'),
 
 
     # Rear ports
     # Rear ports
@@ -383,8 +378,8 @@ urlpatterns = [
     path('rear-ports/<int:pk>/', views.RearPortView.as_view(), name='rearport'),
     path('rear-ports/<int:pk>/', views.RearPortView.as_view(), name='rearport'),
     path('rear-ports/<int:pk>/edit/', views.RearPortEditView.as_view(), name='rearport_edit'),
     path('rear-ports/<int:pk>/edit/', views.RearPortEditView.as_view(), name='rearport_edit'),
     path('rear-ports/<int:pk>/delete/', views.RearPortDeleteView.as_view(), name='rearport_delete'),
     path('rear-ports/<int:pk>/delete/', views.RearPortDeleteView.as_view(), name='rearport_delete'),
-    path('rear-ports/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rearport_changelog', kwargs={'model': RearPort}),
     path('rear-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='rearport_trace', kwargs={'model': RearPort}),
     path('rear-ports/<int:pk>/trace/', views.PathTraceView.as_view(), name='rearport_trace', kwargs={'model': RearPort}),
+    path('rear-ports/<int:pk>/', include(get_model_urls('dcim', 'rearport'))),
     path('devices/rear-ports/add/', views.DeviceBulkAddRearPortView.as_view(), name='device_bulk_add_rearport'),
     path('devices/rear-ports/add/', views.DeviceBulkAddRearPortView.as_view(), name='device_bulk_add_rearport'),
 
 
     # Module bays
     # Module bays
@@ -397,7 +392,7 @@ urlpatterns = [
     path('module-bays/<int:pk>/', views.ModuleBayView.as_view(), name='modulebay'),
     path('module-bays/<int:pk>/', views.ModuleBayView.as_view(), name='modulebay'),
     path('module-bays/<int:pk>/edit/', views.ModuleBayEditView.as_view(), name='modulebay_edit'),
     path('module-bays/<int:pk>/edit/', views.ModuleBayEditView.as_view(), name='modulebay_edit'),
     path('module-bays/<int:pk>/delete/', views.ModuleBayDeleteView.as_view(), name='modulebay_delete'),
     path('module-bays/<int:pk>/delete/', views.ModuleBayDeleteView.as_view(), name='modulebay_delete'),
-    path('module-bays/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='modulebay_changelog', kwargs={'model': ModuleBay}),
+    path('module-bays/<int:pk>/', include(get_model_urls('dcim', 'modulebay'))),
     path('devices/module-bays/add/', views.DeviceBulkAddModuleBayView.as_view(), name='device_bulk_add_modulebay'),
     path('devices/module-bays/add/', views.DeviceBulkAddModuleBayView.as_view(), name='device_bulk_add_modulebay'),
 
 
     # Device bays
     # Device bays
@@ -410,9 +405,9 @@ urlpatterns = [
     path('device-bays/<int:pk>/', views.DeviceBayView.as_view(), name='devicebay'),
     path('device-bays/<int:pk>/', views.DeviceBayView.as_view(), name='devicebay'),
     path('device-bays/<int:pk>/edit/', views.DeviceBayEditView.as_view(), name='devicebay_edit'),
     path('device-bays/<int:pk>/edit/', views.DeviceBayEditView.as_view(), name='devicebay_edit'),
     path('device-bays/<int:pk>/delete/', views.DeviceBayDeleteView.as_view(), name='devicebay_delete'),
     path('device-bays/<int:pk>/delete/', views.DeviceBayDeleteView.as_view(), name='devicebay_delete'),
-    path('device-bays/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='devicebay_changelog', kwargs={'model': DeviceBay}),
     path('device-bays/<int:pk>/populate/', views.DeviceBayPopulateView.as_view(), name='devicebay_populate'),
     path('device-bays/<int:pk>/populate/', views.DeviceBayPopulateView.as_view(), name='devicebay_populate'),
     path('device-bays/<int:pk>/depopulate/', views.DeviceBayDepopulateView.as_view(), name='devicebay_depopulate'),
     path('device-bays/<int:pk>/depopulate/', views.DeviceBayDepopulateView.as_view(), name='devicebay_depopulate'),
+    path('device-bays/<int:pk>/', include(get_model_urls('dcim', 'devicebay'))),
     path('devices/device-bays/add/', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'),
     path('devices/device-bays/add/', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'),
 
 
     # Inventory items
     # Inventory items
@@ -425,10 +420,10 @@ urlpatterns = [
     path('inventory-items/<int:pk>/', views.InventoryItemView.as_view(), name='inventoryitem'),
     path('inventory-items/<int:pk>/', views.InventoryItemView.as_view(), name='inventoryitem'),
     path('inventory-items/<int:pk>/edit/', views.InventoryItemEditView.as_view(), name='inventoryitem_edit'),
     path('inventory-items/<int:pk>/edit/', views.InventoryItemEditView.as_view(), name='inventoryitem_edit'),
     path('inventory-items/<int:pk>/delete/', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'),
     path('inventory-items/<int:pk>/delete/', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'),
-    path('inventory-items/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='inventoryitem_changelog', kwargs={'model': InventoryItem}),
+    path('inventory-items/<int:pk>/', include(get_model_urls('dcim', 'inventoryitem'))),
     path('devices/inventory-items/add/', views.DeviceBulkAddInventoryItemView.as_view(), name='device_bulk_add_inventoryitem'),
     path('devices/inventory-items/add/', views.DeviceBulkAddInventoryItemView.as_view(), name='device_bulk_add_inventoryitem'),
 
 
-    # Device roles
+    # Inventory item roles
     path('inventory-item-roles/', views.InventoryItemRoleListView.as_view(), name='inventoryitemrole_list'),
     path('inventory-item-roles/', views.InventoryItemRoleListView.as_view(), name='inventoryitemrole_list'),
     path('inventory-item-roles/add/', views.InventoryItemRoleEditView.as_view(), name='inventoryitemrole_add'),
     path('inventory-item-roles/add/', views.InventoryItemRoleEditView.as_view(), name='inventoryitemrole_add'),
     path('inventory-item-roles/import/', views.InventoryItemRoleBulkImportView.as_view(), name='inventoryitemrole_import'),
     path('inventory-item-roles/import/', views.InventoryItemRoleBulkImportView.as_view(), name='inventoryitemrole_import'),
@@ -437,7 +432,7 @@ urlpatterns = [
     path('inventory-item-roles/<int:pk>/', views.InventoryItemRoleView.as_view(), name='inventoryitemrole'),
     path('inventory-item-roles/<int:pk>/', views.InventoryItemRoleView.as_view(), name='inventoryitemrole'),
     path('inventory-item-roles/<int:pk>/edit/', views.InventoryItemRoleEditView.as_view(), name='inventoryitemrole_edit'),
     path('inventory-item-roles/<int:pk>/edit/', views.InventoryItemRoleEditView.as_view(), name='inventoryitemrole_edit'),
     path('inventory-item-roles/<int:pk>/delete/', views.InventoryItemRoleDeleteView.as_view(), name='inventoryitemrole_delete'),
     path('inventory-item-roles/<int:pk>/delete/', views.InventoryItemRoleDeleteView.as_view(), name='inventoryitemrole_delete'),
-    path('inventory-item-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='inventoryitemrole_changelog', kwargs={'model': InventoryItemRole}),
+    path('inventory-item-roles/<int:pk>/', include(get_model_urls('dcim', 'inventoryitemrole'))),
 
 
     # Cables
     # Cables
     path('cables/', views.CableListView.as_view(), name='cable_list'),
     path('cables/', views.CableListView.as_view(), name='cable_list'),
@@ -448,8 +443,7 @@ urlpatterns = [
     path('cables/<int:pk>/', views.CableView.as_view(), name='cable'),
     path('cables/<int:pk>/', views.CableView.as_view(), name='cable'),
     path('cables/<int:pk>/edit/', views.CableEditView.as_view(), name='cable_edit'),
     path('cables/<int:pk>/edit/', views.CableEditView.as_view(), name='cable_edit'),
     path('cables/<int:pk>/delete/', views.CableDeleteView.as_view(), name='cable_delete'),
     path('cables/<int:pk>/delete/', views.CableDeleteView.as_view(), name='cable_delete'),
-    path('cables/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='cable_changelog', kwargs={'model': Cable}),
-    path('cables/<int:pk>/journal/', ObjectJournalView.as_view(), name='cable_journal', kwargs={'model': Cable}),
+    path('cables/<int:pk>/', include(get_model_urls('dcim', 'cable'))),
 
 
     # Console/power/interface connections (read-only)
     # Console/power/interface connections (read-only)
     path('console-connections/', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
     path('console-connections/', views.ConsoleConnectionsListView.as_view(), name='console_connections_list'),
@@ -465,9 +459,8 @@ urlpatterns = [
     path('virtual-chassis/<int:pk>/', views.VirtualChassisView.as_view(), name='virtualchassis'),
     path('virtual-chassis/<int:pk>/', views.VirtualChassisView.as_view(), name='virtualchassis'),
     path('virtual-chassis/<int:pk>/edit/', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'),
     path('virtual-chassis/<int:pk>/edit/', views.VirtualChassisEditView.as_view(), name='virtualchassis_edit'),
     path('virtual-chassis/<int:pk>/delete/', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'),
     path('virtual-chassis/<int:pk>/delete/', views.VirtualChassisDeleteView.as_view(), name='virtualchassis_delete'),
-    path('virtual-chassis/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='virtualchassis_changelog', kwargs={'model': VirtualChassis}),
-    path('virtual-chassis/<int:pk>/journal/', ObjectJournalView.as_view(), name='virtualchassis_journal', kwargs={'model': VirtualChassis}),
     path('virtual-chassis/<int:pk>/add-member/', views.VirtualChassisAddMemberView.as_view(), name='virtualchassis_add_member'),
     path('virtual-chassis/<int:pk>/add-member/', views.VirtualChassisAddMemberView.as_view(), name='virtualchassis_add_member'),
+    path('virtual-chassis/<int:pk>/', include(get_model_urls('dcim', 'virtualchassis'))),
     path('virtual-chassis-members/<int:pk>/delete/', views.VirtualChassisRemoveMemberView.as_view(), name='virtualchassis_remove_member'),
     path('virtual-chassis-members/<int:pk>/delete/', views.VirtualChassisRemoveMemberView.as_view(), name='virtualchassis_remove_member'),
 
 
     # Power panels
     # Power panels
@@ -479,8 +472,7 @@ urlpatterns = [
     path('power-panels/<int:pk>/', views.PowerPanelView.as_view(), name='powerpanel'),
     path('power-panels/<int:pk>/', views.PowerPanelView.as_view(), name='powerpanel'),
     path('power-panels/<int:pk>/edit/', views.PowerPanelEditView.as_view(), name='powerpanel_edit'),
     path('power-panels/<int:pk>/edit/', views.PowerPanelEditView.as_view(), name='powerpanel_edit'),
     path('power-panels/<int:pk>/delete/', views.PowerPanelDeleteView.as_view(), name='powerpanel_delete'),
     path('power-panels/<int:pk>/delete/', views.PowerPanelDeleteView.as_view(), name='powerpanel_delete'),
-    path('power-panels/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='powerpanel_changelog', kwargs={'model': PowerPanel}),
-    path('power-panels/<int:pk>/journal/', ObjectJournalView.as_view(), name='powerpanel_journal', kwargs={'model': PowerPanel}),
+    path('power-panels/<int:pk>/', include(get_model_urls('dcim', 'powerpanel'))),
 
 
     # Power feeds
     # Power feeds
     path('power-feeds/', views.PowerFeedListView.as_view(), name='powerfeed_list'),
     path('power-feeds/', views.PowerFeedListView.as_view(), name='powerfeed_list'),
@@ -493,7 +485,6 @@ urlpatterns = [
     path('power-feeds/<int:pk>/edit/', views.PowerFeedEditView.as_view(), name='powerfeed_edit'),
     path('power-feeds/<int:pk>/edit/', views.PowerFeedEditView.as_view(), name='powerfeed_edit'),
     path('power-feeds/<int:pk>/delete/', views.PowerFeedDeleteView.as_view(), name='powerfeed_delete'),
     path('power-feeds/<int:pk>/delete/', views.PowerFeedDeleteView.as_view(), name='powerfeed_delete'),
     path('power-feeds/<int:pk>/trace/', views.PathTraceView.as_view(), name='powerfeed_trace', kwargs={'model': PowerFeed}),
     path('power-feeds/<int:pk>/trace/', views.PathTraceView.as_view(), name='powerfeed_trace', kwargs={'model': PowerFeed}),
-    path('power-feeds/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='powerfeed_changelog', kwargs={'model': PowerFeed}),
-    path('power-feeds/<int:pk>/journal/', ObjectJournalView.as_view(), name='powerfeed_journal', kwargs={'model': PowerFeed}),
+    path('power-feeds/<int:pk>/', include(get_model_urls('dcim', 'powerfeed'))),
 
 
 ]
 ]

+ 10 - 17
netbox/extras/urls.py

@@ -1,7 +1,7 @@
-from django.urls import path, re_path
+from django.urls import include, path, re_path
 
 
-from extras import models, views
-from netbox.views.generic import ObjectChangeLogView
+from extras import views
+from utilities.urls import get_model_urls
 
 
 
 
 app_name = 'extras'
 app_name = 'extras'
@@ -16,8 +16,7 @@ urlpatterns = [
     path('custom-fields/<int:pk>/', views.CustomFieldView.as_view(), name='customfield'),
     path('custom-fields/<int:pk>/', views.CustomFieldView.as_view(), name='customfield'),
     path('custom-fields/<int:pk>/edit/', views.CustomFieldEditView.as_view(), name='customfield_edit'),
     path('custom-fields/<int:pk>/edit/', views.CustomFieldEditView.as_view(), name='customfield_edit'),
     path('custom-fields/<int:pk>/delete/', views.CustomFieldDeleteView.as_view(), name='customfield_delete'),
     path('custom-fields/<int:pk>/delete/', views.CustomFieldDeleteView.as_view(), name='customfield_delete'),
-    path('custom-fields/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='customfield_changelog',
-         kwargs={'model': models.CustomField}),
+    path('custom-fields/<int:pk>/', include(get_model_urls('extras', 'customfield'))),
 
 
     # Custom links
     # Custom links
     path('custom-links/', views.CustomLinkListView.as_view(), name='customlink_list'),
     path('custom-links/', views.CustomLinkListView.as_view(), name='customlink_list'),
@@ -28,8 +27,7 @@ urlpatterns = [
     path('custom-links/<int:pk>/', views.CustomLinkView.as_view(), name='customlink'),
     path('custom-links/<int:pk>/', views.CustomLinkView.as_view(), name='customlink'),
     path('custom-links/<int:pk>/edit/', views.CustomLinkEditView.as_view(), name='customlink_edit'),
     path('custom-links/<int:pk>/edit/', views.CustomLinkEditView.as_view(), name='customlink_edit'),
     path('custom-links/<int:pk>/delete/', views.CustomLinkDeleteView.as_view(), name='customlink_delete'),
     path('custom-links/<int:pk>/delete/', views.CustomLinkDeleteView.as_view(), name='customlink_delete'),
-    path('custom-links/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='customlink_changelog',
-         kwargs={'model': models.CustomLink}),
+    path('custom-links/<int:pk>/', include(get_model_urls('extras', 'customlink'))),
 
 
     # Export templates
     # Export templates
     path('export-templates/', views.ExportTemplateListView.as_view(), name='exporttemplate_list'),
     path('export-templates/', views.ExportTemplateListView.as_view(), name='exporttemplate_list'),
@@ -40,8 +38,7 @@ urlpatterns = [
     path('export-templates/<int:pk>/', views.ExportTemplateView.as_view(), name='exporttemplate'),
     path('export-templates/<int:pk>/', views.ExportTemplateView.as_view(), name='exporttemplate'),
     path('export-templates/<int:pk>/edit/', views.ExportTemplateEditView.as_view(), name='exporttemplate_edit'),
     path('export-templates/<int:pk>/edit/', views.ExportTemplateEditView.as_view(), name='exporttemplate_edit'),
     path('export-templates/<int:pk>/delete/', views.ExportTemplateDeleteView.as_view(), name='exporttemplate_delete'),
     path('export-templates/<int:pk>/delete/', views.ExportTemplateDeleteView.as_view(), name='exporttemplate_delete'),
-    path('export-templates/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='exporttemplate_changelog',
-         kwargs={'model': models.ExportTemplate}),
+    path('export-templates/<int:pk>/', include(get_model_urls('extras', 'exporttemplate'))),
 
 
     # Webhooks
     # Webhooks
     path('webhooks/', views.WebhookListView.as_view(), name='webhook_list'),
     path('webhooks/', views.WebhookListView.as_view(), name='webhook_list'),
@@ -52,8 +49,7 @@ urlpatterns = [
     path('webhooks/<int:pk>/', views.WebhookView.as_view(), name='webhook'),
     path('webhooks/<int:pk>/', views.WebhookView.as_view(), name='webhook'),
     path('webhooks/<int:pk>/edit/', views.WebhookEditView.as_view(), name='webhook_edit'),
     path('webhooks/<int:pk>/edit/', views.WebhookEditView.as_view(), name='webhook_edit'),
     path('webhooks/<int:pk>/delete/', views.WebhookDeleteView.as_view(), name='webhook_delete'),
     path('webhooks/<int:pk>/delete/', views.WebhookDeleteView.as_view(), name='webhook_delete'),
-    path('webhooks/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='webhook_changelog',
-         kwargs={'model': models.Webhook}),
+    path('webhooks/<int:pk>/', include(get_model_urls('extras', 'webhook'))),
 
 
     # Tags
     # Tags
     path('tags/', views.TagListView.as_view(), name='tag_list'),
     path('tags/', views.TagListView.as_view(), name='tag_list'),
@@ -64,8 +60,7 @@ urlpatterns = [
     path('tags/<int:pk>/', views.TagView.as_view(), name='tag'),
     path('tags/<int:pk>/', views.TagView.as_view(), name='tag'),
     path('tags/<int:pk>/edit/', views.TagEditView.as_view(), name='tag_edit'),
     path('tags/<int:pk>/edit/', views.TagEditView.as_view(), name='tag_edit'),
     path('tags/<int:pk>/delete/', views.TagDeleteView.as_view(), name='tag_delete'),
     path('tags/<int:pk>/delete/', views.TagDeleteView.as_view(), name='tag_delete'),
-    path('tags/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='tag_changelog',
-         kwargs={'model': models.Tag}),
+    path('tags/<int:pk>/', include(get_model_urls('extras', 'tag'))),
 
 
     # Config contexts
     # Config contexts
     path('config-contexts/', views.ConfigContextListView.as_view(), name='configcontext_list'),
     path('config-contexts/', views.ConfigContextListView.as_view(), name='configcontext_list'),
@@ -75,8 +70,7 @@ urlpatterns = [
     path('config-contexts/<int:pk>/', views.ConfigContextView.as_view(), name='configcontext'),
     path('config-contexts/<int:pk>/', views.ConfigContextView.as_view(), name='configcontext'),
     path('config-contexts/<int:pk>/edit/', views.ConfigContextEditView.as_view(), name='configcontext_edit'),
     path('config-contexts/<int:pk>/edit/', views.ConfigContextEditView.as_view(), name='configcontext_edit'),
     path('config-contexts/<int:pk>/delete/', views.ConfigContextDeleteView.as_view(), name='configcontext_delete'),
     path('config-contexts/<int:pk>/delete/', views.ConfigContextDeleteView.as_view(), name='configcontext_delete'),
-    path('config-contexts/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='configcontext_changelog',
-         kwargs={'model': models.ConfigContext}),
+    path('config-contexts/<int:pk>/', include(get_model_urls('extras', 'configcontext'))),
 
 
     # Image attachments
     # Image attachments
     path('image-attachments/add/', views.ImageAttachmentEditView.as_view(), name='imageattachment_add'),
     path('image-attachments/add/', views.ImageAttachmentEditView.as_view(), name='imageattachment_add'),
@@ -91,8 +85,7 @@ urlpatterns = [
     path('journal-entries/<int:pk>/', views.JournalEntryView.as_view(), name='journalentry'),
     path('journal-entries/<int:pk>/', views.JournalEntryView.as_view(), name='journalentry'),
     path('journal-entries/<int:pk>/edit/', views.JournalEntryEditView.as_view(), name='journalentry_edit'),
     path('journal-entries/<int:pk>/edit/', views.JournalEntryEditView.as_view(), name='journalentry_edit'),
     path('journal-entries/<int:pk>/delete/', views.JournalEntryDeleteView.as_view(), name='journalentry_delete'),
     path('journal-entries/<int:pk>/delete/', views.JournalEntryDeleteView.as_view(), name='journalentry_delete'),
-    path('journal-entries/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='journalentry_changelog',
-         kwargs={'model': models.JournalEntry}),
+    path('journal-entries/<int:pk>/', include(get_model_urls('extras', 'journalentry'))),
 
 
     # Change logging
     # Change logging
     path('changelog/', views.ObjectChangeListView.as_view(), name='objectchange_list'),
     path('changelog/', views.ObjectChangeListView.as_view(), name='objectchange_list'),

+ 19 - 32
netbox/ipam/urls.py

@@ -1,8 +1,7 @@
-from django.urls import path
+from django.urls import include, path
 
 
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import *
 
 
 app_name = 'ipam'
 app_name = 'ipam'
 urlpatterns = [
 urlpatterns = [
@@ -16,8 +15,7 @@ urlpatterns = [
     path('asns/<int:pk>/', views.ASNView.as_view(), name='asn'),
     path('asns/<int:pk>/', views.ASNView.as_view(), name='asn'),
     path('asns/<int:pk>/edit/', views.ASNEditView.as_view(), name='asn_edit'),
     path('asns/<int:pk>/edit/', views.ASNEditView.as_view(), name='asn_edit'),
     path('asns/<int:pk>/delete/', views.ASNDeleteView.as_view(), name='asn_delete'),
     path('asns/<int:pk>/delete/', views.ASNDeleteView.as_view(), name='asn_delete'),
-    path('asns/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='asn_changelog', kwargs={'model': ASN}),
-    path('asns/<int:pk>/journal/', ObjectJournalView.as_view(), name='asn_journal', kwargs={'model': ASN}),
+    path('asns/<int:pk>/', include(get_model_urls('ipam', 'asn'))),
 
 
     # VRFs
     # VRFs
     path('vrfs/', views.VRFListView.as_view(), name='vrf_list'),
     path('vrfs/', views.VRFListView.as_view(), name='vrf_list'),
@@ -28,8 +26,7 @@ urlpatterns = [
     path('vrfs/<int:pk>/', views.VRFView.as_view(), name='vrf'),
     path('vrfs/<int:pk>/', views.VRFView.as_view(), name='vrf'),
     path('vrfs/<int:pk>/edit/', views.VRFEditView.as_view(), name='vrf_edit'),
     path('vrfs/<int:pk>/edit/', views.VRFEditView.as_view(), name='vrf_edit'),
     path('vrfs/<int:pk>/delete/', views.VRFDeleteView.as_view(), name='vrf_delete'),
     path('vrfs/<int:pk>/delete/', views.VRFDeleteView.as_view(), name='vrf_delete'),
-    path('vrfs/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='vrf_changelog', kwargs={'model': VRF}),
-    path('vrfs/<int:pk>/journal/', ObjectJournalView.as_view(), name='vrf_journal', kwargs={'model': VRF}),
+    path('vrfs/<int:pk>/', include(get_model_urls('ipam', 'vrf'))),
 
 
     # Route targets
     # Route targets
     path('route-targets/', views.RouteTargetListView.as_view(), name='routetarget_list'),
     path('route-targets/', views.RouteTargetListView.as_view(), name='routetarget_list'),
@@ -40,8 +37,7 @@ urlpatterns = [
     path('route-targets/<int:pk>/', views.RouteTargetView.as_view(), name='routetarget'),
     path('route-targets/<int:pk>/', views.RouteTargetView.as_view(), name='routetarget'),
     path('route-targets/<int:pk>/edit/', views.RouteTargetEditView.as_view(), name='routetarget_edit'),
     path('route-targets/<int:pk>/edit/', views.RouteTargetEditView.as_view(), name='routetarget_edit'),
     path('route-targets/<int:pk>/delete/', views.RouteTargetDeleteView.as_view(), name='routetarget_delete'),
     path('route-targets/<int:pk>/delete/', views.RouteTargetDeleteView.as_view(), name='routetarget_delete'),
-    path('route-targets/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='routetarget_changelog', kwargs={'model': RouteTarget}),
-    path('route-targets/<int:pk>/journal/', ObjectJournalView.as_view(), name='routetarget_journal', kwargs={'model': RouteTarget}),
+    path('route-targets/<int:pk>/', include(get_model_urls('ipam', 'routetarget'))),
 
 
     # RIRs
     # RIRs
     path('rirs/', views.RIRListView.as_view(), name='rir_list'),
     path('rirs/', views.RIRListView.as_view(), name='rir_list'),
@@ -52,7 +48,7 @@ urlpatterns = [
     path('rirs/<int:pk>/', views.RIRView.as_view(), name='rir'),
     path('rirs/<int:pk>/', views.RIRView.as_view(), name='rir'),
     path('rirs/<int:pk>/edit/', views.RIREditView.as_view(), name='rir_edit'),
     path('rirs/<int:pk>/edit/', views.RIREditView.as_view(), name='rir_edit'),
     path('rirs/<int:pk>/delete/', views.RIRDeleteView.as_view(), name='rir_delete'),
     path('rirs/<int:pk>/delete/', views.RIRDeleteView.as_view(), name='rir_delete'),
-    path('rirs/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rir_changelog', kwargs={'model': RIR}),
+    path('rirs/<int:pk>/', include(get_model_urls('ipam', 'rir'))),
 
 
     # Aggregates
     # Aggregates
     path('aggregates/', views.AggregateListView.as_view(), name='aggregate_list'),
     path('aggregates/', views.AggregateListView.as_view(), name='aggregate_list'),
@@ -64,8 +60,7 @@ urlpatterns = [
     path('aggregates/<int:pk>/prefixes/', views.AggregatePrefixesView.as_view(), name='aggregate_prefixes'),
     path('aggregates/<int:pk>/prefixes/', views.AggregatePrefixesView.as_view(), name='aggregate_prefixes'),
     path('aggregates/<int:pk>/edit/', views.AggregateEditView.as_view(), name='aggregate_edit'),
     path('aggregates/<int:pk>/edit/', views.AggregateEditView.as_view(), name='aggregate_edit'),
     path('aggregates/<int:pk>/delete/', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
     path('aggregates/<int:pk>/delete/', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
-    path('aggregates/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='aggregate_changelog', kwargs={'model': Aggregate}),
-    path('aggregates/<int:pk>/journal/', ObjectJournalView.as_view(), name='aggregate_journal', kwargs={'model': Aggregate}),
+    path('aggregates/<int:pk>/', include(get_model_urls('ipam', 'aggregate'))),
 
 
     # Roles
     # Roles
     path('roles/', views.RoleListView.as_view(), name='role_list'),
     path('roles/', views.RoleListView.as_view(), name='role_list'),
@@ -76,7 +71,7 @@ urlpatterns = [
     path('roles/<int:pk>/', views.RoleView.as_view(), name='role'),
     path('roles/<int:pk>/', views.RoleView.as_view(), name='role'),
     path('roles/<int:pk>/edit/', views.RoleEditView.as_view(), name='role_edit'),
     path('roles/<int:pk>/edit/', views.RoleEditView.as_view(), name='role_edit'),
     path('roles/<int:pk>/delete/', views.RoleDeleteView.as_view(), name='role_delete'),
     path('roles/<int:pk>/delete/', views.RoleDeleteView.as_view(), name='role_delete'),
-    path('roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='role_changelog', kwargs={'model': Role}),
+    path('roles/<int:pk>/', include(get_model_urls('ipam', 'role'))),
 
 
     # Prefixes
     # Prefixes
     path('prefixes/', views.PrefixListView.as_view(), name='prefix_list'),
     path('prefixes/', views.PrefixListView.as_view(), name='prefix_list'),
@@ -87,11 +82,10 @@ urlpatterns = [
     path('prefixes/<int:pk>/', views.PrefixView.as_view(), name='prefix'),
     path('prefixes/<int:pk>/', views.PrefixView.as_view(), name='prefix'),
     path('prefixes/<int:pk>/edit/', views.PrefixEditView.as_view(), name='prefix_edit'),
     path('prefixes/<int:pk>/edit/', views.PrefixEditView.as_view(), name='prefix_edit'),
     path('prefixes/<int:pk>/delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'),
     path('prefixes/<int:pk>/delete/', views.PrefixDeleteView.as_view(), name='prefix_delete'),
-    path('prefixes/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='prefix_changelog', kwargs={'model': Prefix}),
-    path('prefixes/<int:pk>/journal/', ObjectJournalView.as_view(), name='prefix_journal', kwargs={'model': Prefix}),
     path('prefixes/<int:pk>/prefixes/', views.PrefixPrefixesView.as_view(), name='prefix_prefixes'),
     path('prefixes/<int:pk>/prefixes/', views.PrefixPrefixesView.as_view(), name='prefix_prefixes'),
     path('prefixes/<int:pk>/ip-ranges/', views.PrefixIPRangesView.as_view(), name='prefix_ipranges'),
     path('prefixes/<int:pk>/ip-ranges/', views.PrefixIPRangesView.as_view(), name='prefix_ipranges'),
     path('prefixes/<int:pk>/ip-addresses/', views.PrefixIPAddressesView.as_view(), name='prefix_ipaddresses'),
     path('prefixes/<int:pk>/ip-addresses/', views.PrefixIPAddressesView.as_view(), name='prefix_ipaddresses'),
+    path('prefixes/<int:pk>/', include(get_model_urls('ipam', 'prefix'))),
 
 
     # IP ranges
     # IP ranges
     path('ip-ranges/', views.IPRangeListView.as_view(), name='iprange_list'),
     path('ip-ranges/', views.IPRangeListView.as_view(), name='iprange_list'),
@@ -102,9 +96,8 @@ urlpatterns = [
     path('ip-ranges/<int:pk>/', views.IPRangeView.as_view(), name='iprange'),
     path('ip-ranges/<int:pk>/', views.IPRangeView.as_view(), name='iprange'),
     path('ip-ranges/<int:pk>/edit/', views.IPRangeEditView.as_view(), name='iprange_edit'),
     path('ip-ranges/<int:pk>/edit/', views.IPRangeEditView.as_view(), name='iprange_edit'),
     path('ip-ranges/<int:pk>/delete/', views.IPRangeDeleteView.as_view(), name='iprange_delete'),
     path('ip-ranges/<int:pk>/delete/', views.IPRangeDeleteView.as_view(), name='iprange_delete'),
-    path('ip-ranges/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='iprange_changelog', kwargs={'model': IPRange}),
-    path('ip-ranges/<int:pk>/journal/', ObjectJournalView.as_view(), name='iprange_journal', kwargs={'model': IPRange}),
     path('ip-ranges/<int:pk>/ip-addresses/', views.IPRangeIPAddressesView.as_view(), name='iprange_ipaddresses'),
     path('ip-ranges/<int:pk>/ip-addresses/', views.IPRangeIPAddressesView.as_view(), name='iprange_ipaddresses'),
+    path('ip-ranges/<int:pk>/', include(get_model_urls('ipam', 'iprange'))),
 
 
     # IP addresses
     # IP addresses
     path('ip-addresses/', views.IPAddressListView.as_view(), name='ipaddress_list'),
     path('ip-addresses/', views.IPAddressListView.as_view(), name='ipaddress_list'),
@@ -113,12 +106,11 @@ urlpatterns = [
     path('ip-addresses/import/', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
     path('ip-addresses/import/', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
     path('ip-addresses/edit/', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
     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/delete/', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
-    path('ip-addresses/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='ipaddress_changelog', kwargs={'model': IPAddress}),
-    path('ip-addresses/<int:pk>/journal/', ObjectJournalView.as_view(), name='ipaddress_journal', kwargs={'model': IPAddress}),
     path('ip-addresses/assign/', views.IPAddressAssignView.as_view(), name='ipaddress_assign'),
     path('ip-addresses/assign/', views.IPAddressAssignView.as_view(), name='ipaddress_assign'),
     path('ip-addresses/<int:pk>/', views.IPAddressView.as_view(), name='ipaddress'),
     path('ip-addresses/<int:pk>/', views.IPAddressView.as_view(), name='ipaddress'),
     path('ip-addresses/<int:pk>/edit/', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
     path('ip-addresses/<int:pk>/edit/', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
     path('ip-addresses/<int:pk>/delete/', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
     path('ip-addresses/<int:pk>/delete/', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
+    path('ip-addresses/<int:pk>/', include(get_model_urls('ipam', 'ipaddress'))),
 
 
     # FHRP groups
     # FHRP groups
     path('fhrp-groups/', views.FHRPGroupListView.as_view(), name='fhrpgroup_list'),
     path('fhrp-groups/', views.FHRPGroupListView.as_view(), name='fhrpgroup_list'),
@@ -129,8 +121,7 @@ urlpatterns = [
     path('fhrp-groups/<int:pk>/', views.FHRPGroupView.as_view(), name='fhrpgroup'),
     path('fhrp-groups/<int:pk>/', views.FHRPGroupView.as_view(), name='fhrpgroup'),
     path('fhrp-groups/<int:pk>/edit/', views.FHRPGroupEditView.as_view(), name='fhrpgroup_edit'),
     path('fhrp-groups/<int:pk>/edit/', views.FHRPGroupEditView.as_view(), name='fhrpgroup_edit'),
     path('fhrp-groups/<int:pk>/delete/', views.FHRPGroupDeleteView.as_view(), name='fhrpgroup_delete'),
     path('fhrp-groups/<int:pk>/delete/', views.FHRPGroupDeleteView.as_view(), name='fhrpgroup_delete'),
-    path('fhrp-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='fhrpgroup_changelog', kwargs={'model': FHRPGroup}),
-    path('fhrp-groups/<int:pk>/journal/', ObjectJournalView.as_view(), name='fhrpgroup_journal', kwargs={'model': FHRPGroup}),
+    path('fhrp-groups/<int:pk>/', include(get_model_urls('ipam', 'fhrpgroup'))),
 
 
     # FHRP group assignments
     # FHRP group assignments
     path('fhrp-group-assignments/add/', views.FHRPGroupAssignmentEditView.as_view(), name='fhrpgroupassignment_add'),
     path('fhrp-group-assignments/add/', views.FHRPGroupAssignmentEditView.as_view(), name='fhrpgroupassignment_add'),
@@ -146,7 +137,7 @@ urlpatterns = [
     path('vlan-groups/<int:pk>/', views.VLANGroupView.as_view(), name='vlangroup'),
     path('vlan-groups/<int:pk>/', views.VLANGroupView.as_view(), name='vlangroup'),
     path('vlan-groups/<int:pk>/edit/', views.VLANGroupEditView.as_view(), name='vlangroup_edit'),
     path('vlan-groups/<int:pk>/edit/', views.VLANGroupEditView.as_view(), name='vlangroup_edit'),
     path('vlan-groups/<int:pk>/delete/', views.VLANGroupDeleteView.as_view(), name='vlangroup_delete'),
     path('vlan-groups/<int:pk>/delete/', views.VLANGroupDeleteView.as_view(), name='vlangroup_delete'),
-    path('vlan-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='vlangroup_changelog', kwargs={'model': VLANGroup}),
+    path('vlan-groups/<int:pk>/', include(get_model_urls('ipam', 'vlangroup'))),
 
 
     # VLANs
     # VLANs
     path('vlans/', views.VLANListView.as_view(), name='vlan_list'),
     path('vlans/', views.VLANListView.as_view(), name='vlan_list'),
@@ -159,8 +150,7 @@ urlpatterns = [
     path('vlans/<int:pk>/vm-interfaces/', views.VLANVMInterfacesView.as_view(), name='vlan_vminterfaces'),
     path('vlans/<int:pk>/vm-interfaces/', views.VLANVMInterfacesView.as_view(), name='vlan_vminterfaces'),
     path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'),
     path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'),
     path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'),
     path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'),
-    path('vlans/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='vlan_changelog', kwargs={'model': VLAN}),
-    path('vlans/<int:pk>/journal/', ObjectJournalView.as_view(), name='vlan_journal', kwargs={'model': VLAN}),
+    path('vlans/<int:pk>/', include(get_model_urls('ipam', 'vlan'))),
 
 
     # Service templates
     # Service templates
     path('service-templates/', views.ServiceTemplateListView.as_view(), name='servicetemplate_list'),
     path('service-templates/', views.ServiceTemplateListView.as_view(), name='servicetemplate_list'),
@@ -171,8 +161,7 @@ urlpatterns = [
     path('service-templates/<int:pk>/', views.ServiceTemplateView.as_view(), name='servicetemplate'),
     path('service-templates/<int:pk>/', views.ServiceTemplateView.as_view(), name='servicetemplate'),
     path('service-templates/<int:pk>/edit/', views.ServiceTemplateEditView.as_view(), name='servicetemplate_edit'),
     path('service-templates/<int:pk>/edit/', views.ServiceTemplateEditView.as_view(), name='servicetemplate_edit'),
     path('service-templates/<int:pk>/delete/', views.ServiceTemplateDeleteView.as_view(), name='servicetemplate_delete'),
     path('service-templates/<int:pk>/delete/', views.ServiceTemplateDeleteView.as_view(), name='servicetemplate_delete'),
-    path('service-templates/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='servicetemplate_changelog', kwargs={'model': ServiceTemplate}),
-    path('service-templates/<int:pk>/journal/', ObjectJournalView.as_view(), name='servicetemplate_journal', kwargs={'model': ServiceTemplate}),
+    path('service-templates/<int:pk>/', include(get_model_urls('ipam', 'servicetemplate'))),
 
 
     # Services
     # Services
     path('services/', views.ServiceListView.as_view(), name='service_list'),
     path('services/', views.ServiceListView.as_view(), name='service_list'),
@@ -183,8 +172,7 @@ urlpatterns = [
     path('services/<int:pk>/', views.ServiceView.as_view(), name='service'),
     path('services/<int:pk>/', views.ServiceView.as_view(), name='service'),
     path('services/<int:pk>/edit/', views.ServiceEditView.as_view(), name='service_edit'),
     path('services/<int:pk>/edit/', views.ServiceEditView.as_view(), name='service_edit'),
     path('services/<int:pk>/delete/', views.ServiceDeleteView.as_view(), name='service_delete'),
     path('services/<int:pk>/delete/', views.ServiceDeleteView.as_view(), name='service_delete'),
-    path('services/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='service_changelog', kwargs={'model': Service}),
-    path('services/<int:pk>/journal/', ObjectJournalView.as_view(), name='service_journal', kwargs={'model': Service}),
+    path('services/<int:pk>/', include(get_model_urls('ipam', 'service'))),
 
 
     # L2VPN
     # L2VPN
     path('l2vpns/', views.L2VPNListView.as_view(), name='l2vpn_list'),
     path('l2vpns/', views.L2VPNListView.as_view(), name='l2vpn_list'),
@@ -195,9 +183,9 @@ urlpatterns = [
     path('l2vpns/<int:pk>/', views.L2VPNView.as_view(), name='l2vpn'),
     path('l2vpns/<int:pk>/', views.L2VPNView.as_view(), name='l2vpn'),
     path('l2vpns/<int:pk>/edit/', views.L2VPNEditView.as_view(), name='l2vpn_edit'),
     path('l2vpns/<int:pk>/edit/', views.L2VPNEditView.as_view(), name='l2vpn_edit'),
     path('l2vpns/<int:pk>/delete/', views.L2VPNDeleteView.as_view(), name='l2vpn_delete'),
     path('l2vpns/<int:pk>/delete/', views.L2VPNDeleteView.as_view(), name='l2vpn_delete'),
-    path('l2vpns/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='l2vpn_changelog', kwargs={'model': L2VPN}),
-    path('l2vpns/<int:pk>/journal/', ObjectJournalView.as_view(), name='l2vpn_journal', kwargs={'model': L2VPN}),
+    path('l2vpns/<int:pk>/', include(get_model_urls('ipam', 'l2vpn'))),
 
 
+    # L2VPN terminations
     path('l2vpn-terminations/', views.L2VPNTerminationListView.as_view(), name='l2vpntermination_list'),
     path('l2vpn-terminations/', views.L2VPNTerminationListView.as_view(), name='l2vpntermination_list'),
     path('l2vpn-terminations/add/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_add'),
     path('l2vpn-terminations/add/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_add'),
     path('l2vpn-terminations/import/', views.L2VPNTerminationBulkImportView.as_view(), name='l2vpntermination_import'),
     path('l2vpn-terminations/import/', views.L2VPNTerminationBulkImportView.as_view(), name='l2vpntermination_import'),
@@ -206,6 +194,5 @@ urlpatterns = [
     path('l2vpn-terminations/<int:pk>/', views.L2VPNTerminationView.as_view(), name='l2vpntermination'),
     path('l2vpn-terminations/<int:pk>/', views.L2VPNTerminationView.as_view(), name='l2vpntermination'),
     path('l2vpn-terminations/<int:pk>/edit/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_edit'),
     path('l2vpn-terminations/<int:pk>/edit/', views.L2VPNTerminationEditView.as_view(), name='l2vpntermination_edit'),
     path('l2vpn-terminations/<int:pk>/delete/', views.L2VPNTerminationDeleteView.as_view(), name='l2vpntermination_delete'),
     path('l2vpn-terminations/<int:pk>/delete/', views.L2VPNTerminationDeleteView.as_view(), name='l2vpntermination_delete'),
-    path('l2vpn-terminations/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='l2vpntermination_changelog', kwargs={'model': L2VPNTermination}),
-    path('l2vpn-terminations/<int:pk>/journal/', ObjectJournalView.as_view(), name='l2vpntermination_journal', kwargs={'model': L2VPNTermination}),
+    path('l2vpn-terminations/<int:pk>/', include(get_model_urls('ipam', 'l2vpntermination'))),
 ]
 ]

+ 7 - 10
netbox/tenancy/urls.py

@@ -1,8 +1,7 @@
-from django.urls import path
+from django.urls import include, path
 
 
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import *
 
 
 app_name = 'tenancy'
 app_name = 'tenancy'
 urlpatterns = [
 urlpatterns = [
@@ -16,7 +15,7 @@ urlpatterns = [
     path('tenant-groups/<int:pk>/', views.TenantGroupView.as_view(), name='tenantgroup'),
     path('tenant-groups/<int:pk>/', views.TenantGroupView.as_view(), name='tenantgroup'),
     path('tenant-groups/<int:pk>/edit/', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'),
     path('tenant-groups/<int:pk>/edit/', views.TenantGroupEditView.as_view(), name='tenantgroup_edit'),
     path('tenant-groups/<int:pk>/delete/', views.TenantGroupDeleteView.as_view(), name='tenantgroup_delete'),
     path('tenant-groups/<int:pk>/delete/', views.TenantGroupDeleteView.as_view(), name='tenantgroup_delete'),
-    path('tenant-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='tenantgroup_changelog', kwargs={'model': TenantGroup}),
+    path('tenant-groups/<int:pk>/', include(get_model_urls('tenancy', 'tenantgroup'))),
 
 
     # Tenants
     # Tenants
     path('tenants/', views.TenantListView.as_view(), name='tenant_list'),
     path('tenants/', views.TenantListView.as_view(), name='tenant_list'),
@@ -27,8 +26,7 @@ urlpatterns = [
     path('tenants/<int:pk>/', views.TenantView.as_view(), name='tenant'),
     path('tenants/<int:pk>/', views.TenantView.as_view(), name='tenant'),
     path('tenants/<int:pk>/edit/', views.TenantEditView.as_view(), name='tenant_edit'),
     path('tenants/<int:pk>/edit/', views.TenantEditView.as_view(), name='tenant_edit'),
     path('tenants/<int:pk>/delete/', views.TenantDeleteView.as_view(), name='tenant_delete'),
     path('tenants/<int:pk>/delete/', views.TenantDeleteView.as_view(), name='tenant_delete'),
-    path('tenants/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='tenant_changelog', kwargs={'model': Tenant}),
-    path('tenants/<int:pk>/journal/', ObjectJournalView.as_view(), name='tenant_journal', kwargs={'model': Tenant}),
+    path('tenants/<int:pk>/', include(get_model_urls('tenancy', 'tenant'))),
 
 
     # Contact groups
     # Contact groups
     path('contact-groups/', views.ContactGroupListView.as_view(), name='contactgroup_list'),
     path('contact-groups/', views.ContactGroupListView.as_view(), name='contactgroup_list'),
@@ -39,7 +37,7 @@ urlpatterns = [
     path('contact-groups/<int:pk>/', views.ContactGroupView.as_view(), name='contactgroup'),
     path('contact-groups/<int:pk>/', views.ContactGroupView.as_view(), name='contactgroup'),
     path('contact-groups/<int:pk>/edit/', views.ContactGroupEditView.as_view(), name='contactgroup_edit'),
     path('contact-groups/<int:pk>/edit/', views.ContactGroupEditView.as_view(), name='contactgroup_edit'),
     path('contact-groups/<int:pk>/delete/', views.ContactGroupDeleteView.as_view(), name='contactgroup_delete'),
     path('contact-groups/<int:pk>/delete/', views.ContactGroupDeleteView.as_view(), name='contactgroup_delete'),
-    path('contact-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='contactgroup_changelog', kwargs={'model': ContactGroup}),
+    path('contact-groups/<int:pk>/', include(get_model_urls('tenancy', 'contactgroup'))),
 
 
     # Contact roles
     # Contact roles
     path('contact-roles/', views.ContactRoleListView.as_view(), name='contactrole_list'),
     path('contact-roles/', views.ContactRoleListView.as_view(), name='contactrole_list'),
@@ -50,7 +48,7 @@ urlpatterns = [
     path('contact-roles/<int:pk>/', views.ContactRoleView.as_view(), name='contactrole'),
     path('contact-roles/<int:pk>/', views.ContactRoleView.as_view(), name='contactrole'),
     path('contact-roles/<int:pk>/edit/', views.ContactRoleEditView.as_view(), name='contactrole_edit'),
     path('contact-roles/<int:pk>/edit/', views.ContactRoleEditView.as_view(), name='contactrole_edit'),
     path('contact-roles/<int:pk>/delete/', views.ContactRoleDeleteView.as_view(), name='contactrole_delete'),
     path('contact-roles/<int:pk>/delete/', views.ContactRoleDeleteView.as_view(), name='contactrole_delete'),
-    path('contact-roles/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='contactrole_changelog', kwargs={'model': ContactRole}),
+    path('contact-roles/<int:pk>/', include(get_model_urls('tenancy', 'contactrole'))),
 
 
     # Contacts
     # Contacts
     path('contacts/', views.ContactListView.as_view(), name='contact_list'),
     path('contacts/', views.ContactListView.as_view(), name='contact_list'),
@@ -61,8 +59,7 @@ urlpatterns = [
     path('contacts/<int:pk>/', views.ContactView.as_view(), name='contact'),
     path('contacts/<int:pk>/', views.ContactView.as_view(), name='contact'),
     path('contacts/<int:pk>/edit/', views.ContactEditView.as_view(), name='contact_edit'),
     path('contacts/<int:pk>/edit/', views.ContactEditView.as_view(), name='contact_edit'),
     path('contacts/<int:pk>/delete/', views.ContactDeleteView.as_view(), name='contact_delete'),
     path('contacts/<int:pk>/delete/', views.ContactDeleteView.as_view(), name='contact_delete'),
-    path('contacts/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='contact_changelog', kwargs={'model': Contact}),
-    path('contacts/<int:pk>/journal/', ObjectJournalView.as_view(), name='contact_journal', kwargs={'model': Contact}),
+    path('contacts/<int:pk>/', include(get_model_urls('tenancy', 'contact'))),
 
 
     # Contact assignments
     # Contact assignments
     path('contact-assignments/add/', views.ContactAssignmentEditView.as_view(), name='contactassignment_add'),
     path('contact-assignments/add/', views.ContactAssignmentEditView.as_view(), name='contactassignment_add'),

+ 7 - 10
netbox/virtualization/urls.py

@@ -1,8 +1,7 @@
-from django.urls import path
+from django.urls import include, path
 
 
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
 
 
 app_name = 'virtualization'
 app_name = 'virtualization'
 urlpatterns = [
 urlpatterns = [
@@ -16,7 +15,7 @@ urlpatterns = [
     path('cluster-types/<int:pk>/', views.ClusterTypeView.as_view(), name='clustertype'),
     path('cluster-types/<int:pk>/', views.ClusterTypeView.as_view(), name='clustertype'),
     path('cluster-types/<int:pk>/edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
     path('cluster-types/<int:pk>/edit/', views.ClusterTypeEditView.as_view(), name='clustertype_edit'),
     path('cluster-types/<int:pk>/delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'),
     path('cluster-types/<int:pk>/delete/', views.ClusterTypeDeleteView.as_view(), name='clustertype_delete'),
-    path('cluster-types/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustertype_changelog', kwargs={'model': ClusterType}),
+    path('cluster-types/<int:pk>/', include(get_model_urls('virtualization', 'clustertype'))),
 
 
     # Cluster groups
     # Cluster groups
     path('cluster-groups/', views.ClusterGroupListView.as_view(), name='clustergroup_list'),
     path('cluster-groups/', views.ClusterGroupListView.as_view(), name='clustergroup_list'),
@@ -27,7 +26,7 @@ urlpatterns = [
     path('cluster-groups/<int:pk>/', views.ClusterGroupView.as_view(), name='clustergroup'),
     path('cluster-groups/<int:pk>/', views.ClusterGroupView.as_view(), name='clustergroup'),
     path('cluster-groups/<int:pk>/edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
     path('cluster-groups/<int:pk>/edit/', views.ClusterGroupEditView.as_view(), name='clustergroup_edit'),
     path('cluster-groups/<int:pk>/delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'),
     path('cluster-groups/<int:pk>/delete/', views.ClusterGroupDeleteView.as_view(), name='clustergroup_delete'),
-    path('cluster-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='clustergroup_changelog', kwargs={'model': ClusterGroup}),
+    path('cluster-groups/<int:pk>/', include(get_model_urls('virtualization', 'clustergroup'))),
 
 
     # Clusters
     # Clusters
     path('clusters/', views.ClusterListView.as_view(), name='cluster_list'),
     path('clusters/', views.ClusterListView.as_view(), name='cluster_list'),
@@ -40,10 +39,9 @@ urlpatterns = [
     path('clusters/<int:pk>/virtual-machines/', views.ClusterVirtualMachinesView.as_view(), name='cluster_virtualmachines'),
     path('clusters/<int:pk>/virtual-machines/', views.ClusterVirtualMachinesView.as_view(), name='cluster_virtualmachines'),
     path('clusters/<int:pk>/edit/', views.ClusterEditView.as_view(), name='cluster_edit'),
     path('clusters/<int:pk>/edit/', views.ClusterEditView.as_view(), name='cluster_edit'),
     path('clusters/<int:pk>/delete/', views.ClusterDeleteView.as_view(), name='cluster_delete'),
     path('clusters/<int:pk>/delete/', views.ClusterDeleteView.as_view(), name='cluster_delete'),
-    path('clusters/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='cluster_changelog', kwargs={'model': Cluster}),
-    path('clusters/<int:pk>/journal/', ObjectJournalView.as_view(), name='cluster_journal', kwargs={'model': Cluster}),
     path('clusters/<int:pk>/devices/add/', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'),
     path('clusters/<int:pk>/devices/add/', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'),
     path('clusters/<int:pk>/devices/remove/', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'),
     path('clusters/<int:pk>/devices/remove/', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'),
+    path('clusters/<int:pk>/', include(get_model_urls('virtualization', 'cluster'))),
 
 
     # Virtual machines
     # Virtual machines
     path('virtual-machines/', views.VirtualMachineListView.as_view(), name='virtualmachine_list'),
     path('virtual-machines/', views.VirtualMachineListView.as_view(), name='virtualmachine_list'),
@@ -56,8 +54,7 @@ urlpatterns = [
     path('virtual-machines/<int:pk>/edit/', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'),
     path('virtual-machines/<int:pk>/edit/', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'),
     path('virtual-machines/<int:pk>/delete/', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'),
     path('virtual-machines/<int:pk>/delete/', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'),
     path('virtual-machines/<int:pk>/config-context/', views.VirtualMachineConfigContextView.as_view(), name='virtualmachine_configcontext'),
     path('virtual-machines/<int:pk>/config-context/', views.VirtualMachineConfigContextView.as_view(), name='virtualmachine_configcontext'),
-    path('virtual-machines/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='virtualmachine_changelog', kwargs={'model': VirtualMachine}),
-    path('virtual-machines/<int:pk>/journal/', ObjectJournalView.as_view(), name='virtualmachine_journal', kwargs={'model': VirtualMachine}),
+    path('virtual-machines/<int:pk>/', include(get_model_urls('virtualization', 'virtualmachine'))),
 
 
     # VM interfaces
     # VM interfaces
     path('interfaces/', views.VMInterfaceListView.as_view(), name='vminterface_list'),
     path('interfaces/', views.VMInterfaceListView.as_view(), name='vminterface_list'),
@@ -69,7 +66,7 @@ urlpatterns = [
     path('interfaces/<int:pk>/', views.VMInterfaceView.as_view(), name='vminterface'),
     path('interfaces/<int:pk>/', views.VMInterfaceView.as_view(), name='vminterface'),
     path('interfaces/<int:pk>/edit/', views.VMInterfaceEditView.as_view(), name='vminterface_edit'),
     path('interfaces/<int:pk>/edit/', views.VMInterfaceEditView.as_view(), name='vminterface_edit'),
     path('interfaces/<int:pk>/delete/', views.VMInterfaceDeleteView.as_view(), name='vminterface_delete'),
     path('interfaces/<int:pk>/delete/', views.VMInterfaceDeleteView.as_view(), name='vminterface_delete'),
-    path('interfaces/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='vminterface_changelog', kwargs={'model': VMInterface}),
+    path('interfaces/<int:pk>/', include(get_model_urls('virtualization', 'vminterface'))),
     path('virtual-machines/interfaces/add/', views.VirtualMachineBulkAddInterfaceView.as_view(), name='virtualmachine_bulk_add_vminterface'),
     path('virtual-machines/interfaces/add/', views.VirtualMachineBulkAddInterfaceView.as_view(), name='virtualmachine_bulk_add_vminterface'),
 
 
 ]
 ]

+ 5 - 8
netbox/wireless/urls.py

@@ -1,8 +1,7 @@
-from django.urls import path
+from django.urls import include, path
 
 
-from netbox.views.generic import ObjectChangeLogView, ObjectJournalView
+from utilities.urls import get_model_urls
 from . import views
 from . import views
-from .models import *
 
 
 app_name = 'wireless'
 app_name = 'wireless'
 urlpatterns = (
 urlpatterns = (
@@ -16,7 +15,7 @@ urlpatterns = (
     path('wireless-lan-groups/<int:pk>/', views.WirelessLANGroupView.as_view(), name='wirelesslangroup'),
     path('wireless-lan-groups/<int:pk>/', views.WirelessLANGroupView.as_view(), name='wirelesslangroup'),
     path('wireless-lan-groups/<int:pk>/edit/', views.WirelessLANGroupEditView.as_view(), name='wirelesslangroup_edit'),
     path('wireless-lan-groups/<int:pk>/edit/', views.WirelessLANGroupEditView.as_view(), name='wirelesslangroup_edit'),
     path('wireless-lan-groups/<int:pk>/delete/', views.WirelessLANGroupDeleteView.as_view(), name='wirelesslangroup_delete'),
     path('wireless-lan-groups/<int:pk>/delete/', views.WirelessLANGroupDeleteView.as_view(), name='wirelesslangroup_delete'),
-    path('wireless-lan-groups/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='wirelesslangroup_changelog', kwargs={'model': WirelessLANGroup}),
+    path('wireless-lan-groups/<int:pk>/', include(get_model_urls('wireless', 'wirelesslangroup'))),
 
 
     # Wireless LANs
     # Wireless LANs
     path('wireless-lans/', views.WirelessLANListView.as_view(), name='wirelesslan_list'),
     path('wireless-lans/', views.WirelessLANListView.as_view(), name='wirelesslan_list'),
@@ -27,8 +26,7 @@ urlpatterns = (
     path('wireless-lans/<int:pk>/', views.WirelessLANView.as_view(), name='wirelesslan'),
     path('wireless-lans/<int:pk>/', views.WirelessLANView.as_view(), name='wirelesslan'),
     path('wireless-lans/<int:pk>/edit/', views.WirelessLANEditView.as_view(), name='wirelesslan_edit'),
     path('wireless-lans/<int:pk>/edit/', views.WirelessLANEditView.as_view(), name='wirelesslan_edit'),
     path('wireless-lans/<int:pk>/delete/', views.WirelessLANDeleteView.as_view(), name='wirelesslan_delete'),
     path('wireless-lans/<int:pk>/delete/', views.WirelessLANDeleteView.as_view(), name='wirelesslan_delete'),
-    path('wireless-lans/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='wirelesslan_changelog', kwargs={'model': WirelessLAN}),
-    path('wireless-lans/<int:pk>/journal/', ObjectJournalView.as_view(), name='wirelesslan_journal', kwargs={'model': WirelessLAN}),
+    path('wireless-lans/<int:pk>/', include(get_model_urls('wireless', 'wirelesslan'))),
 
 
     # Wireless links
     # Wireless links
     path('wireless-links/', views.WirelessLinkListView.as_view(), name='wirelesslink_list'),
     path('wireless-links/', views.WirelessLinkListView.as_view(), name='wirelesslink_list'),
@@ -39,7 +37,6 @@ urlpatterns = (
     path('wireless-links/<int:pk>/', views.WirelessLinkView.as_view(), name='wirelesslink'),
     path('wireless-links/<int:pk>/', views.WirelessLinkView.as_view(), name='wirelesslink'),
     path('wireless-links/<int:pk>/edit/', views.WirelessLinkEditView.as_view(), name='wirelesslink_edit'),
     path('wireless-links/<int:pk>/edit/', views.WirelessLinkEditView.as_view(), name='wirelesslink_edit'),
     path('wireless-links/<int:pk>/delete/', views.WirelessLinkDeleteView.as_view(), name='wirelesslink_delete'),
     path('wireless-links/<int:pk>/delete/', views.WirelessLinkDeleteView.as_view(), name='wirelesslink_delete'),
-    path('wireless-links/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='wirelesslink_changelog', kwargs={'model': WirelessLink}),
-    path('wireless-links/<int:pk>/journal/', ObjectJournalView.as_view(), name='wirelesslink_journal', kwargs={'model': WirelessLink}),
+    path('wireless-links/<int:pk>/', include(get_model_urls('wireless', 'wirelesslink'))),
 
 
 )
 )