Просмотр исходного кода

Split out NetBoxTable from BaseTable

jeremystretch 4 лет назад
Родитель
Сommit
59d3f5c4ea

+ 9 - 13
netbox/circuits/tables.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from .models import *
 
@@ -47,8 +47,7 @@ class CommitRateColumn(tables.TemplateColumn):
 # Providers
 #
 
-class ProviderTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ProviderTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -61,7 +60,7 @@ class ProviderTable(BaseTable):
         url_name='circuits:provider_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Provider
         fields = (
             'pk', 'id', 'name', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'circuit_count',
@@ -74,8 +73,7 @@ class ProviderTable(BaseTable):
 # Provider networks
 #
 
-class ProviderNetworkTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ProviderNetworkTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -87,7 +85,7 @@ class ProviderNetworkTable(BaseTable):
         url_name='circuits:providernetwork_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ProviderNetwork
         fields = (
             'pk', 'id', 'name', 'provider', 'service_id', 'description', 'comments', 'created', 'last_updated', 'tags',
@@ -99,8 +97,7 @@ class ProviderNetworkTable(BaseTable):
 # Circuit types
 #
 
-class CircuitTypeTable(BaseTable):
-    pk = columns.ToggleColumn()
+class CircuitTypeTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -111,7 +108,7 @@ class CircuitTypeTable(BaseTable):
         verbose_name='Circuits'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = CircuitType
         fields = (
             'pk', 'id', 'name', 'circuit_count', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
@@ -123,8 +120,7 @@ class CircuitTypeTable(BaseTable):
 # Circuits
 #
 
-class CircuitTable(BaseTable):
-    pk = columns.ToggleColumn()
+class CircuitTable(NetBoxTable):
     cid = tables.Column(
         linkify=True,
         verbose_name='Circuit ID'
@@ -148,7 +144,7 @@ class CircuitTable(BaseTable):
         url_name='circuits:circuit_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Circuit
         fields = (
             'pk', 'id', 'cid', 'provider', 'type', 'status', 'tenant', 'termination_a', 'termination_z', 'install_date',

+ 1 - 4
netbox/dcim/tables/__init__.py

@@ -1,8 +1,8 @@
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 
-from dcim.models import ConsolePort, Interface, PowerPort
 from netbox.tables import BaseTable, columns
+from dcim.models import ConsolePort, Interface, PowerPort
 from .cables import *
 from .devices import *
 from .devicetypes import *
@@ -44,7 +44,6 @@ class ConsoleConnectionTable(BaseTable):
     class Meta(BaseTable.Meta):
         model = ConsolePort
         fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable')
-        exclude = ('id', )
 
 
 class PowerConnectionTable(BaseTable):
@@ -75,7 +74,6 @@ class PowerConnectionTable(BaseTable):
     class Meta(BaseTable.Meta):
         model = PowerPort
         fields = ('device', 'name', 'pdu', 'outlet', 'reachable')
-        exclude = ('id', )
 
 
 class InterfaceConnectionTable(BaseTable):
@@ -109,4 +107,3 @@ class InterfaceConnectionTable(BaseTable):
     class Meta(BaseTable.Meta):
         model = Interface
         fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable')
-        exclude = ('id', )

+ 3 - 4
netbox/dcim/tables/cables.py

@@ -2,7 +2,7 @@ import django_tables2 as tables
 from django_tables2.utils import Accessor
 
 from dcim.models import Cable
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from .template_code import CABLE_LENGTH, CABLE_TERMINATION_PARENT
 
@@ -15,8 +15,7 @@ __all__ = (
 # Cables
 #
 
-class CableTable(BaseTable):
-    pk = columns.ToggleColumn()
+class CableTable(NetBoxTable):
     termination_a_parent = tables.TemplateColumn(
         template_code=CABLE_TERMINATION_PARENT,
         accessor=Accessor('termination_a'),
@@ -52,7 +51,7 @@ class CableTable(BaseTable):
         url_name='dcim:cable_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Cable
         fields = (
             'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b',

+ 19 - 25
netbox/dcim/tables/devices.py

@@ -5,7 +5,7 @@ from dcim.models import (
     ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, FrontPort, Interface, InventoryItem,
     InventoryItemRole, ModuleBay, Platform, PowerOutlet, PowerPort, RearPort, VirtualChassis,
 )
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from .template_code import *
 
@@ -71,8 +71,7 @@ def get_interface_state_attribute(record):
 # Device roles
 #
 
-class DeviceRoleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class DeviceRoleTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -92,7 +91,7 @@ class DeviceRoleTable(BaseTable):
         url_name='dcim:devicerole_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = DeviceRole
         fields = (
             'pk', 'id', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'tags',
@@ -105,8 +104,7 @@ class DeviceRoleTable(BaseTable):
 # Platforms
 #
 
-class PlatformTable(BaseTable):
-    pk = columns.ToggleColumn()
+class PlatformTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -124,7 +122,7 @@ class PlatformTable(BaseTable):
         url_name='dcim:platform_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Platform
         fields = (
             'pk', 'id', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args',
@@ -139,8 +137,7 @@ class PlatformTable(BaseTable):
 # Devices
 #
 
-class DeviceTable(BaseTable):
-    pk = columns.ToggleColumn()
+class DeviceTable(NetBoxTable):
     name = tables.TemplateColumn(
         order_by=('_name',),
         template_code=DEVICE_LINK
@@ -197,7 +194,7 @@ class DeviceTable(BaseTable):
         url_name='dcim:device_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Device
         fields = (
             'pk', 'id', 'name', 'status', 'tenant', 'device_role', 'manufacturer', 'device_type', 'platform', 'serial',
@@ -211,7 +208,7 @@ class DeviceTable(BaseTable):
         )
 
 
-class DeviceImportTable(BaseTable):
+class DeviceImportTable(NetBoxTable):
     name = tables.TemplateColumn(
         template_code=DEVICE_LINK
     )
@@ -230,7 +227,7 @@ class DeviceImportTable(BaseTable):
         verbose_name='Type'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Device
         fields = ('id', 'name', 'status', 'tenant', 'site', 'rack', 'position', 'device_role', 'device_type')
         empty_text = False
@@ -240,8 +237,7 @@ class DeviceImportTable(BaseTable):
 # Device components
 #
 
-class DeviceComponentTable(BaseTable):
-    pk = columns.ToggleColumn()
+class DeviceComponentTable(NetBoxTable):
     device = tables.Column(
         linkify=True
     )
@@ -250,7 +246,7 @@ class DeviceComponentTable(BaseTable):
         order_by=('_name',)
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         order_by = ('device', 'name')
 
 
@@ -267,7 +263,7 @@ class ModularDeviceComponentTable(DeviceComponentTable):
     )
 
 
-class CableTerminationTable(BaseTable):
+class CableTerminationTable(NetBoxTable):
     cable = tables.Column(
         linkify=True
     )
@@ -473,7 +469,7 @@ class DevicePowerOutletTable(PowerOutletTable):
         }
 
 
-class BaseInterfaceTable(BaseTable):
+class BaseInterfaceTable(NetBoxTable):
     enabled = columns.BooleanColumn()
     ip_addresses = tables.TemplateColumn(
         template_code=INTERFACE_IPADDRESSES,
@@ -776,7 +772,7 @@ class InventoryItemTable(DeviceComponentTable):
     )
     cable = None  # Override DeviceComponentTable
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = InventoryItem
         fields = (
             'pk', 'id', 'name', 'device', 'component', 'label', 'role', 'manufacturer', 'part_id', 'serial',
@@ -796,7 +792,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
     )
     actions = columns.ActionsColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = InventoryItem
         fields = (
             'pk', 'id', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component',
@@ -807,8 +803,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
         )
 
 
-class InventoryItemRoleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class InventoryItemRoleTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -822,7 +817,7 @@ class InventoryItemRoleTable(BaseTable):
         url_name='dcim:inventoryitemrole_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = InventoryItemRole
         fields = (
             'pk', 'id', 'name', 'inventoryitem_count', 'color', 'description', 'slug', 'tags', 'actions',
@@ -834,8 +829,7 @@ class InventoryItemRoleTable(BaseTable):
 # Virtual chassis
 #
 
-class VirtualChassisTable(BaseTable):
-    pk = columns.ToggleColumn()
+class VirtualChassisTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -851,7 +845,7 @@ class VirtualChassisTable(BaseTable):
         url_name='dcim:virtualchassis_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VirtualChassis
         fields = ('pk', 'id', 'name', 'domain', 'master', 'member_count', 'tags', 'created', 'last_updated',)
         default_columns = ('pk', 'name', 'domain', 'master', 'member_count')

+ 7 - 10
netbox/dcim/tables/devicetypes.py

@@ -5,7 +5,7 @@ from dcim.models import (
     ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, DeviceType, FrontPortTemplate, InterfaceTemplate,
     InventoryItemTemplate, Manufacturer, ModuleBayTemplate, PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
 )
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS
 
 __all__ = (
@@ -28,8 +28,7 @@ __all__ = (
 # Manufacturers
 #
 
-class ManufacturerTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ManufacturerTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -47,7 +46,7 @@ class ManufacturerTable(BaseTable):
         url_name='dcim:manufacturer_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Manufacturer
         fields = (
             'pk', 'id', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug',
@@ -62,8 +61,7 @@ class ManufacturerTable(BaseTable):
 # Device types
 #
 
-class DeviceTypeTable(BaseTable):
-    pk = columns.ToggleColumn()
+class DeviceTypeTable(NetBoxTable):
     model = tables.Column(
         linkify=True,
         verbose_name='Device Type'
@@ -81,7 +79,7 @@ class DeviceTypeTable(BaseTable):
         url_name='dcim:devicetype_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = DeviceType
         fields = (
             'pk', 'id', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role',
@@ -96,8 +94,7 @@ class DeviceTypeTable(BaseTable):
 # Device type components
 #
 
-class ComponentTemplateTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ComponentTemplateTable(NetBoxTable):
     id = tables.Column(
         verbose_name='ID'
     )
@@ -105,7 +102,7 @@ class ComponentTemplateTable(BaseTable):
         order_by=('_name',)
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         exclude = ('id', )
 
 

+ 5 - 7
netbox/dcim/tables/modules.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from dcim.models import Module, ModuleType
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 
 __all__ = (
     'ModuleTable',
@@ -9,8 +9,7 @@ __all__ = (
 )
 
 
-class ModuleTypeTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ModuleTypeTable(NetBoxTable):
     model = tables.Column(
         linkify=True,
         verbose_name='Module Type'
@@ -25,7 +24,7 @@ class ModuleTypeTable(BaseTable):
         url_name='dcim:moduletype_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ModuleType
         fields = (
             'pk', 'id', 'model', 'manufacturer', 'part_number', 'comments', 'tags',
@@ -35,8 +34,7 @@ class ModuleTypeTable(BaseTable):
         )
 
 
-class ModuleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ModuleTable(NetBoxTable):
     device = tables.Column(
         linkify=True
     )
@@ -51,7 +49,7 @@ class ModuleTable(BaseTable):
         url_name='dcim:module_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Module
         fields = (
             'pk', 'id', 'device', 'module_bay', 'module_type', 'serial', 'asset_tag', 'comments', 'tags',

+ 4 - 6
netbox/dcim/tables/power.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from dcim.models import PowerFeed, PowerPanel
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from .devices import CableTerminationTable
 
 __all__ = (
@@ -14,8 +14,7 @@ __all__ = (
 # Power panels
 #
 
-class PowerPanelTable(BaseTable):
-    pk = columns.ToggleColumn()
+class PowerPanelTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -31,7 +30,7 @@ class PowerPanelTable(BaseTable):
         url_name='dcim:powerpanel_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = PowerPanel
         fields = ('pk', 'id', 'name', 'site', 'location', 'powerfeed_count', 'tags', 'created', 'last_updated',)
         default_columns = ('pk', 'name', 'site', 'location', 'powerfeed_count')
@@ -44,7 +43,6 @@ class PowerPanelTable(BaseTable):
 # We're not using PathEndpointTable for PowerFeed because power connections
 # cannot traverse pass-through ports.
 class PowerFeedTable(CableTerminationTable):
-    pk = columns.ToggleColumn()
     name = tables.Column(
         linkify=True
     )
@@ -67,7 +65,7 @@ class PowerFeedTable(CableTerminationTable):
         url_name='dcim:powerfeed_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = PowerFeed
         fields = (
             'pk', 'id', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',

+ 7 - 10
netbox/dcim/tables/racks.py

@@ -2,7 +2,7 @@ import django_tables2 as tables
 from django_tables2.utils import Accessor
 
 from dcim.models import Rack, RackReservation, RackRole
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 
 __all__ = (
@@ -16,8 +16,7 @@ __all__ = (
 # Rack roles
 #
 
-class RackRoleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RackRoleTable(NetBoxTable):
     name = tables.Column(linkify=True)
     rack_count = tables.Column(verbose_name='Racks')
     color = columns.ColorColumn()
@@ -25,7 +24,7 @@ class RackRoleTable(BaseTable):
         url_name='dcim:rackrole_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = RackRole
         fields = (
             'pk', 'id', 'name', 'rack_count', 'color', 'description', 'slug', 'tags', 'actions', 'created',
@@ -38,8 +37,7 @@ class RackRoleTable(BaseTable):
 # Racks
 #
 
-class RackTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RackTable(NetBoxTable):
     name = tables.Column(
         order_by=('_name',),
         linkify=True
@@ -83,7 +81,7 @@ class RackTable(BaseTable):
         verbose_name='Outer Depth'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Rack
         fields = (
             'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag',
@@ -100,8 +98,7 @@ class RackTable(BaseTable):
 # Rack reservations
 #
 
-class RackReservationTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RackReservationTable(NetBoxTable):
     reservation = tables.Column(
         accessor='pk',
         linkify=True
@@ -122,7 +119,7 @@ class RackReservationTable(BaseTable):
         url_name='dcim:rackreservation_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = RackReservation
         fields = (
             'pk', 'id', 'reservation', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'tags',

+ 9 - 13
netbox/dcim/tables/sites.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from dcim.models import Location, Region, Site, SiteGroup
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from .template_code import LOCATION_BUTTONS
 
@@ -17,8 +17,7 @@ __all__ = (
 # Regions
 #
 
-class RegionTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RegionTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -31,7 +30,7 @@ class RegionTable(BaseTable):
         url_name='dcim:region_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Region
         fields = (
             'pk', 'id', 'name', 'slug', 'site_count', 'description', 'tags', 'created', 'last_updated', 'actions',
@@ -43,8 +42,7 @@ class RegionTable(BaseTable):
 # Site groups
 #
 
-class SiteGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class SiteGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -57,7 +55,7 @@ class SiteGroupTable(BaseTable):
         url_name='dcim:sitegroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = SiteGroup
         fields = (
             'pk', 'id', 'name', 'slug', 'site_count', 'description', 'tags', 'created', 'last_updated', 'actions',
@@ -69,8 +67,7 @@ class SiteGroupTable(BaseTable):
 # Sites
 #
 
-class SiteTable(BaseTable):
-    pk = columns.ToggleColumn()
+class SiteTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -93,7 +90,7 @@ class SiteTable(BaseTable):
         url_name='dcim:site_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Site
         fields = (
             'pk', 'id', 'name', 'slug', 'status', 'facility', 'region', 'group', 'tenant', 'asn_count', 'time_zone',
@@ -107,8 +104,7 @@ class SiteTable(BaseTable):
 # Locations
 #
 
-class LocationTable(BaseTable):
-    pk = columns.ToggleColumn()
+class LocationTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -133,7 +129,7 @@ class LocationTable(BaseTable):
         extra_buttons=LOCATION_BUTTONS
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Location
         fields = (
             'pk', 'id', 'name', 'site', 'tenant', 'rack_count', 'device_count', 'description', 'slug', 'tags',

+ 20 - 27
netbox/extras/tables.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 from django.conf import settings
 
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from .models import *
 
 __all__ = (
@@ -43,15 +43,14 @@ OBJECTCHANGE_REQUEST_ID = """
 # Custom fields
 #
 
-class CustomFieldTable(BaseTable):
-    pk = columns.ToggleColumn()
+class CustomFieldTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
     content_types = columns.ContentTypesColumn()
     required = columns.BooleanColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = CustomField
         fields = (
             'pk', 'id', 'name', 'content_types', 'label', 'type', 'required', 'weight', 'default',
@@ -64,8 +63,7 @@ class CustomFieldTable(BaseTable):
 # Custom links
 #
 
-class CustomLinkTable(BaseTable):
-    pk = columns.ToggleColumn()
+class CustomLinkTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -73,7 +71,7 @@ class CustomLinkTable(BaseTable):
     enabled = columns.BooleanColumn()
     new_window = columns.BooleanColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = CustomLink
         fields = (
             'pk', 'id', 'name', 'content_type', 'enabled', 'link_text', 'link_url', 'weight', 'group_name',
@@ -86,15 +84,14 @@ class CustomLinkTable(BaseTable):
 # Export templates
 #
 
-class ExportTemplateTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ExportTemplateTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
     content_type = columns.ContentTypeColumn()
     as_attachment = columns.BooleanColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ExportTemplate
         fields = (
             'pk', 'id', 'name', 'content_type', 'description', 'mime_type', 'file_extension', 'as_attachment',
@@ -109,8 +106,7 @@ class ExportTemplateTable(BaseTable):
 # Webhooks
 #
 
-class WebhookTable(BaseTable):
-    pk = columns.ToggleColumn()
+class WebhookTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -129,7 +125,7 @@ class WebhookTable(BaseTable):
         verbose_name='SSL Validation'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Webhook
         fields = (
             'pk', 'id', 'name', 'content_types', 'enabled', 'type_create', 'type_update', 'type_delete', 'http_method',
@@ -145,20 +141,19 @@ class WebhookTable(BaseTable):
 # Tags
 #
 
-class TagTable(BaseTable):
-    pk = columns.ToggleColumn()
+class TagTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
     color = columns.ColorColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Tag
         fields = ('pk', 'id', 'name', 'items', 'slug', 'color', 'description', 'created', 'last_updated', 'actions')
         default_columns = ('pk', 'name', 'items', 'slug', 'color', 'description')
 
 
-class TaggedItemTable(BaseTable):
+class TaggedItemTable(NetBoxTable):
     id = tables.Column(
         verbose_name='ID',
         linkify=lambda record: record.content_object.get_absolute_url(),
@@ -173,13 +168,12 @@ class TaggedItemTable(BaseTable):
         verbose_name='Object'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = TaggedItem
         fields = ('id', 'content_type', 'content_object')
 
 
-class ConfigContextTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ConfigContextTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -187,7 +181,7 @@ class ConfigContextTable(BaseTable):
         verbose_name='Active'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ConfigContext
         fields = (
             'pk', 'id', 'name', 'weight', 'is_active', 'description', 'regions', 'sites', 'roles',
@@ -197,7 +191,7 @@ class ConfigContextTable(BaseTable):
         default_columns = ('pk', 'name', 'weight', 'is_active', 'description')
 
 
-class ObjectChangeTable(BaseTable):
+class ObjectChangeTable(NetBoxTable):
     time = tables.DateTimeColumn(
         linkify=True,
         format=settings.SHORT_DATETIME_FORMAT
@@ -216,12 +210,12 @@ class ObjectChangeTable(BaseTable):
     )
     actions = columns.ActionsColumn(sequence=())
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ObjectChange
         fields = ('id', 'time', 'user_name', 'action', 'changed_object_type', 'object_repr', 'request_id')
 
 
-class ObjectJournalTable(BaseTable):
+class ObjectJournalTable(NetBoxTable):
     """
     Used for displaying a set of JournalEntries within the context of a single object.
     """
@@ -234,13 +228,12 @@ class ObjectJournalTable(BaseTable):
         template_code='{% load helpers %}{{ value|render_markdown|truncatewords_html:50 }}'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = JournalEntry
         fields = ('id', 'created', 'created_by', 'kind', 'comments', 'actions')
 
 
 class JournalEntryTable(ObjectJournalTable):
-    pk = columns.ToggleColumn()
     assigned_object_type = columns.ContentTypeColumn(
         verbose_name='Object type'
     )
@@ -251,7 +244,7 @@ class JournalEntryTable(ObjectJournalTable):
     )
     comments = columns.MarkdownColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = JournalEntry
         fields = (
             'pk', 'id', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'kind',

+ 5 - 7
netbox/ipam/tables/fhrp.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from ipam.models import *
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 
 __all__ = (
     'FHRPGroupTable',
@@ -16,8 +16,7 @@ IPADDRESSES = """
 """
 
 
-class FHRPGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class FHRPGroupTable(NetBoxTable):
     group_id = tables.Column(
         linkify=True
     )
@@ -34,7 +33,7 @@ class FHRPGroupTable(BaseTable):
         url_name='ipam:fhrpgroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = FHRPGroup
         fields = (
             'pk', 'group_id', 'protocol', 'auth_type', 'auth_key', 'description', 'ip_addresses', 'interface_count',
@@ -43,8 +42,7 @@ class FHRPGroupTable(BaseTable):
         default_columns = ('pk', 'group_id', 'protocol', 'auth_type', 'description', 'ip_addresses', 'interface_count')
 
 
-class FHRPGroupAssignmentTable(BaseTable):
-    pk = columns.ToggleColumn()
+class FHRPGroupAssignmentTable(NetBoxTable):
     interface_parent = tables.Column(
         accessor=tables.A('interface.parent_object'),
         linkify=True,
@@ -62,7 +60,7 @@ class FHRPGroupAssignmentTable(BaseTable):
         sequence=('edit', 'delete')
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = FHRPGroupAssignment
         fields = ('pk', 'group', 'interface_parent', 'interface', 'priority')
         exclude = ('id',)

+ 19 - 26
netbox/ipam/tables/ip.py

@@ -3,7 +3,7 @@ from django.utils.safestring import mark_safe
 from django_tables2.utils import Accessor
 
 from ipam.models import *
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 
 __all__ = (
@@ -70,8 +70,7 @@ VRF_LINK = """
 # RIRs
 #
 
-class RIRTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RIRTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -87,7 +86,7 @@ class RIRTable(BaseTable):
         url_name='ipam:rir_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = RIR
         fields = (
             'pk', 'id', 'name', 'slug', 'is_private', 'aggregate_count', 'description', 'tags', 'created',
@@ -100,8 +99,7 @@ class RIRTable(BaseTable):
 # ASNs
 #
 
-class ASNTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ASNTable(NetBoxTable):
     asn = tables.Column(
         accessor=tables.A('asn_asdot'),
         linkify=True
@@ -113,7 +111,7 @@ class ASNTable(BaseTable):
         verbose_name='Sites'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ASN
         fields = ('pk', 'asn', 'rir', 'site_count', 'tenant', 'description', 'created', 'last_updated', 'actions')
         default_columns = ('pk', 'asn', 'rir', 'site_count', 'sites', 'tenant')
@@ -123,8 +121,7 @@ class ASNTable(BaseTable):
 # Aggregates
 #
 
-class AggregateTable(BaseTable):
-    pk = columns.ToggleColumn()
+class AggregateTable(NetBoxTable):
     prefix = tables.Column(
         linkify=True,
         verbose_name='Aggregate'
@@ -145,7 +142,7 @@ class AggregateTable(BaseTable):
         url_name='ipam:aggregate_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Aggregate
         fields = (
             'pk', 'id', 'prefix', 'rir', 'tenant', 'child_count', 'utilization', 'date_added', 'description', 'tags',
@@ -158,8 +155,7 @@ class AggregateTable(BaseTable):
 # Roles
 #
 
-class RoleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RoleTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -177,7 +173,7 @@ class RoleTable(BaseTable):
         url_name='ipam:role_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Role
         fields = (
             'pk', 'id', 'name', 'slug', 'prefix_count', 'vlan_count', 'description', 'weight', 'tags', 'created',
@@ -205,8 +201,7 @@ class PrefixUtilizationColumn(columns.UtilizationColumn):
     """
 
 
-class PrefixTable(BaseTable):
-    pk = columns.ToggleColumn()
+class PrefixTable(NetBoxTable):
     prefix = tables.TemplateColumn(
         template_code=PREFIX_LINK,
         attrs={'td': {'class': 'text-nowrap'}}
@@ -266,7 +261,7 @@ class PrefixTable(BaseTable):
         url_name='ipam:prefix_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Prefix
         fields = (
             'pk', 'id', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site',
@@ -283,8 +278,7 @@ class PrefixTable(BaseTable):
 #
 # IP ranges
 #
-class IPRangeTable(BaseTable):
-    pk = columns.ToggleColumn()
+class IPRangeTable(NetBoxTable):
     start_address = tables.Column(
         linkify=True
     )
@@ -307,7 +301,7 @@ class IPRangeTable(BaseTable):
         url_name='ipam:iprange_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = IPRange
         fields = (
             'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description',
@@ -325,8 +319,7 @@ class IPRangeTable(BaseTable):
 # IPAddresses
 #
 
-class IPAddressTable(BaseTable):
-    pk = columns.ToggleColumn()
+class IPAddressTable(NetBoxTable):
     address = tables.TemplateColumn(
         template_code=IPADDRESS_LINK,
         verbose_name='IP Address'
@@ -365,7 +358,7 @@ class IPAddressTable(BaseTable):
         url_name='ipam:ipaddress_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = IPAddress
         fields = (
             'pk', 'id', 'address', 'vrf', 'status', 'role', 'tenant', 'nat_inside', 'assigned', 'dns_name', 'description',
@@ -379,7 +372,7 @@ class IPAddressTable(BaseTable):
         }
 
 
-class IPAddressAssignTable(BaseTable):
+class IPAddressAssignTable(NetBoxTable):
     address = tables.TemplateColumn(
         template_code=IPADDRESS_ASSIGN_LINK,
         verbose_name='IP Address'
@@ -389,14 +382,14 @@ class IPAddressAssignTable(BaseTable):
         orderable=False
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = IPAddress
         fields = ('address', 'dns_name', 'vrf', 'status', 'role', 'tenant', 'assigned_object', 'description')
         exclude = ('id', )
         orderable = False
 
 
-class AssignedIPAddressesTable(BaseTable):
+class AssignedIPAddressesTable(NetBoxTable):
     """
     List IP addresses assigned to an object.
     """
@@ -411,7 +404,7 @@ class AssignedIPAddressesTable(BaseTable):
     status = columns.ChoiceFieldColumn()
     tenant = TenantColumn()
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = IPAddress
         fields = ('address', 'vrf', 'status', 'role', 'tenant', 'description')
         exclude = ('id', )

+ 5 - 7
netbox/ipam/tables/services.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from ipam.models import *
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 
 __all__ = (
     'ServiceTable',
@@ -9,8 +9,7 @@ __all__ = (
 )
 
 
-class ServiceTemplateTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ServiceTemplateTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -21,14 +20,13 @@ class ServiceTemplateTable(BaseTable):
         url_name='ipam:servicetemplate_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ServiceTemplate
         fields = ('pk', 'id', 'name', 'protocol', 'ports', 'description', 'tags')
         default_columns = ('pk', 'name', 'protocol', 'ports', 'description')
 
 
-class ServiceTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ServiceTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -43,7 +41,7 @@ class ServiceTable(BaseTable):
         url_name='ipam:service_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Service
         fields = (
             'pk', 'id', 'name', 'parent', 'protocol', 'ports', 'ipaddresses', 'description', 'tags', 'created',

+ 10 - 12
netbox/ipam/tables/vlans.py

@@ -4,7 +4,7 @@ from django_tables2.utils import Accessor
 
 from dcim.models import Interface
 from ipam.models import *
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from virtualization.models import VMInterface
 
@@ -58,8 +58,7 @@ VLAN_MEMBER_TAGGED = """
 # VLAN groups
 #
 
-class VLANGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class VLANGroupTable(NetBoxTable):
     name = tables.Column(linkify=True)
     scope_type = columns.ContentTypeColumn()
     scope = tables.Column(
@@ -78,7 +77,7 @@ class VLANGroupTable(BaseTable):
         extra_buttons=VLANGROUP_BUTTONS
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VLANGroup
         fields = (
             'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description',
@@ -91,8 +90,7 @@ class VLANGroupTable(BaseTable):
 # VLANs
 #
 
-class VLANTable(BaseTable):
-    pk = columns.ToggleColumn()
+class VLANTable(NetBoxTable):
     vid = tables.TemplateColumn(
         template_code=VLAN_LINK,
         verbose_name='VID'
@@ -122,7 +120,7 @@ class VLANTable(BaseTable):
         url_name='ipam:vlan_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VLAN
         fields = (
             'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description', 'tags',
@@ -134,7 +132,7 @@ class VLANTable(BaseTable):
         }
 
 
-class VLANMembersTable(BaseTable):
+class VLANMembersTable(NetBoxTable):
     """
     Base table for Interface and VMInterface assignments
     """
@@ -156,7 +154,7 @@ class VLANDevicesTable(VLANMembersTable):
         sequence=('edit',)
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Interface
         fields = ('device', 'name', 'tagged', 'actions')
         exclude = ('id', )
@@ -170,13 +168,13 @@ class VLANVirtualMachinesTable(VLANMembersTable):
         sequence=('edit',)
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VMInterface
         fields = ('virtual_machine', 'name', 'tagged', 'actions')
         exclude = ('id', )
 
 
-class InterfaceVLANTable(BaseTable):
+class InterfaceVLANTable(NetBoxTable):
     """
     List VLANs assigned to a specific Interface.
     """
@@ -198,7 +196,7 @@ class InterfaceVLANTable(BaseTable):
         linkify=True
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VLAN
         fields = ('vid', 'tagged', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description')
         exclude = ('id', )

+ 5 - 7
netbox/ipam/tables/vrfs.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from ipam.models import *
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 
 __all__ = (
@@ -20,8 +20,7 @@ VRF_TARGETS = """
 # VRFs
 #
 
-class VRFTable(BaseTable):
-    pk = columns.ToggleColumn()
+class VRFTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -44,7 +43,7 @@ class VRFTable(BaseTable):
         url_name='ipam:vrf_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VRF
         fields = (
             'pk', 'id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'export_targets',
@@ -57,8 +56,7 @@ class VRFTable(BaseTable):
 # Route targets
 #
 
-class RouteTargetTable(BaseTable):
-    pk = columns.ToggleColumn()
+class RouteTargetTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -67,7 +65,7 @@ class RouteTargetTable(BaseTable):
         url_name='ipam:vrf_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = RouteTarget
         fields = ('pk', 'id', 'name', 'tenant', 'description', 'tags', 'created', 'last_updated',)
         default_columns = ('pk', 'name', 'tenant', 'description')

+ 54 - 25
netbox/netbox/tables/tables.py

@@ -11,49 +11,37 @@ from netbox.tables import columns
 
 __all__ = (
     'BaseTable',
+    'NetBoxTable',
 )
 
 
 class BaseTable(tables.Table):
     """
-    Default table for object lists
+    Base table class for NetBox objects. Adds support for:
+
+        * User configuration (column preferences)
+        * Automatic prefetching of related objects
+        * BS5 styling
 
     :param user: Personalize table display for the given user (optional). Has no effect if AnonymousUser is passed.
     """
-    id = tables.Column(
-        linkify=True,
-        verbose_name='ID'
-    )
-    actions = columns.ActionsColumn()
+    exempt_columns = ()
 
     class Meta:
         attrs = {
             'class': 'table table-hover object-list',
         }
 
-    def __init__(self, *args, user=None, extra_columns=None, **kwargs):
-        if extra_columns is None:
-            extra_columns = []
+    def __init__(self, *args, user=None, **kwargs):
 
-        # Add custom field & custom link columns
-        content_type = ContentType.objects.get_for_model(self._meta.model)
-        custom_fields = CustomField.objects.filter(content_types=content_type)
-        extra_columns.extend([
-            (f'cf_{cf.name}', columns.CustomFieldColumn(cf)) for cf in custom_fields
-        ])
-        custom_links = CustomLink.objects.filter(content_type=content_type, enabled=True)
-        extra_columns.extend([
-            (f'cl_{cl.name}', columns.CustomLinkColumn(cl)) for cl in custom_links
-        ])
-
-        super().__init__(*args, extra_columns=extra_columns, **kwargs)
+        super().__init__(*args, **kwargs)
 
         # Set default empty_text if none was provided
         if self.empty_text is None:
             self.empty_text = f"No {self._meta.model._meta.verbose_name_plural} found"
 
-        # Hide non-default columns (except for actions)
-        default_columns = [*getattr(self.Meta, 'default_columns', self.Meta.fields), 'actions']
+        # Hide non-default columns
+        default_columns = [*getattr(self.Meta, 'default_columns', self.Meta.fields), *self.exempt_columns]
         for column in self.columns:
             if column.name not in default_columns:
                 self.columns.hide(column.name)
@@ -65,7 +53,7 @@ class BaseTable(tables.Table):
 
                 # Show only persistent or selected columns
                 for name, column in self.columns.items():
-                    if name in ['pk', 'actions', *selected_columns]:
+                    if name in [*self.exempt_columns, *selected_columns]:
                         self.columns.show(name)
                     else:
                         self.columns.hide(name)
@@ -116,7 +104,7 @@ class BaseTable(tables.Table):
     def _get_columns(self, visible=True):
         columns = []
         for name, column in self.columns.items():
-            if column.visible == visible and name not in ['pk', 'actions']:
+            if column.visible == visible and name not in self.exempt_columns:
                 columns.append((name, column.verbose_name))
         return columns
 
@@ -137,3 +125,44 @@ class BaseTable(tables.Table):
         if not hasattr(self, '_objects_count'):
             self._objects_count = sum(1 for obj in self.data if hasattr(obj, 'pk'))
         return self._objects_count
+
+
+class NetBoxTable(BaseTable):
+    """
+    Table class for most NetBox objects. Adds support for custom field & custom link columns. Includes
+    default columns for:
+
+        * PK (row selection)
+        * ID
+        * Actions
+    """
+    pk = columns.ToggleColumn(
+        visible=False
+    )
+    id = tables.Column(
+        linkify=True,
+        verbose_name='ID'
+    )
+    actions = columns.ActionsColumn()
+
+    exempt_columns = ('pk', 'actions')
+
+    class Meta(BaseTable.Meta):
+        pass
+
+    def __init__(self, *args, extra_columns=None, **kwargs):
+        if extra_columns is None:
+            extra_columns = []
+
+        # Add custom field & custom link columns
+        content_type = ContentType.objects.get_for_model(self._meta.model)
+        custom_fields = CustomField.objects.filter(content_types=content_type)
+        extra_columns.extend([
+            (f'cf_{cf.name}', columns.CustomFieldColumn(cf)) for cf in custom_fields
+        ])
+        custom_links = CustomLink.objects.filter(content_type=content_type, enabled=True)
+        extra_columns.extend([
+            (f'cl_{cl.name}', columns.CustomLinkColumn(cl)) for cl in custom_links
+        ])
+
+        super().__init__(*args, extra_columns=extra_columns, **kwargs)

+ 3 - 3
netbox/utilities/tests/test_tables.py → netbox/netbox/tests/test_tables.py

@@ -2,14 +2,14 @@ from django.template import Context, Template
 from django.test import TestCase
 
 from dcim.models import Site
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from utilities.testing import create_tags
 
 
-class TagColumnTable(BaseTable):
+class TagColumnTable(NetBoxTable):
     tags = columns.TagColumn(url_name='dcim:site_list')
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Site
         fields = ('pk', 'name', 'tags',)
         default_columns = fields

+ 13 - 19
netbox/tenancy/tables.py

@@ -1,6 +1,6 @@
 import django_tables2 as tables
 
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from utilities.tables import linkify_phone
 from .models import *
 
@@ -44,8 +44,7 @@ class TenantColumn(tables.TemplateColumn):
 # Tenants
 #
 
-class TenantGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class TenantGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -58,7 +57,7 @@ class TenantGroupTable(BaseTable):
         url_name='tenancy:tenantgroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = TenantGroup
         fields = (
             'pk', 'id', 'name', 'tenant_count', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
@@ -66,8 +65,7 @@ class TenantGroupTable(BaseTable):
         default_columns = ('pk', 'name', 'tenant_count', 'description')
 
 
-class TenantTable(BaseTable):
-    pk = columns.ToggleColumn()
+class TenantTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -79,7 +77,7 @@ class TenantTable(BaseTable):
         url_name='tenancy:tenant_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Tenant
         fields = ('pk', 'id', 'name', 'slug', 'group', 'description', 'comments', 'tags', 'created', 'last_updated',)
         default_columns = ('pk', 'name', 'group', 'description')
@@ -89,8 +87,7 @@ class TenantTable(BaseTable):
 # Contacts
 #
 
-class ContactGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ContactGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -103,7 +100,7 @@ class ContactGroupTable(BaseTable):
         url_name='tenancy:contactgroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ContactGroup
         fields = (
             'pk', 'name', 'contact_count', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
@@ -111,20 +108,18 @@ class ContactGroupTable(BaseTable):
         default_columns = ('pk', 'name', 'contact_count', 'description')
 
 
-class ContactRoleTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ContactRoleTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ContactRole
         fields = ('pk', 'name', 'description', 'slug', 'created', 'last_updated', 'actions')
         default_columns = ('pk', 'name', 'description')
 
 
-class ContactTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ContactTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -142,7 +137,7 @@ class ContactTable(BaseTable):
         url_name='tenancy:tenant_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Contact
         fields = (
             'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'assignment_count', 'tags',
@@ -151,8 +146,7 @@ class ContactTable(BaseTable):
         default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email')
 
 
-class ContactAssignmentTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ContactAssignmentTable(NetBoxTable):
     content_type = columns.ContentTypeColumn(
         verbose_name='Object Type'
     )
@@ -170,7 +164,7 @@ class ContactAssignmentTable(BaseTable):
         sequence=('edit', 'delete')
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ContactAssignment
         fields = ('pk', 'content_type', 'object', 'contact', 'role', 'priority', 'actions')
         default_columns = ('pk', 'content_type', 'object', 'contact', 'role', 'priority')

+ 11 - 16
netbox/virtualization/tables.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from dcim.tables.devices import BaseInterfaceTable
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from tenancy.tables import TenantColumn
 from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
 
@@ -27,8 +27,7 @@ VMINTERFACE_BUTTONS = """
 # Cluster types
 #
 
-class ClusterTypeTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ClusterTypeTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -39,7 +38,7 @@ class ClusterTypeTable(BaseTable):
         url_name='virtualization:clustertype_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ClusterType
         fields = (
             'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'created', 'last_updated', 'tags', 'actions',
@@ -51,8 +50,7 @@ class ClusterTypeTable(BaseTable):
 # Cluster groups
 #
 
-class ClusterGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ClusterGroupTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -63,7 +61,7 @@ class ClusterGroupTable(BaseTable):
         url_name='virtualization:clustergroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = ClusterGroup
         fields = (
             'pk', 'id', 'name', 'slug', 'cluster_count', 'description', 'tags', 'created', 'last_updated', 'actions',
@@ -75,8 +73,7 @@ class ClusterGroupTable(BaseTable):
 # Clusters
 #
 
-class ClusterTable(BaseTable):
-    pk = columns.ToggleColumn()
+class ClusterTable(NetBoxTable):
     name = tables.Column(
         linkify=True
     )
@@ -107,7 +104,7 @@ class ClusterTable(BaseTable):
         url_name='virtualization:cluster_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Cluster
         fields = (
             'pk', 'id', 'name', 'type', 'group', 'tenant', 'site', 'comments', 'device_count', 'vm_count', 'tags',
@@ -120,8 +117,7 @@ class ClusterTable(BaseTable):
 # Virtual machines
 #
 
-class VirtualMachineTable(BaseTable):
-    pk = columns.ToggleColumn()
+class VirtualMachineTable(NetBoxTable):
     name = tables.Column(
         order_by=('_name',),
         linkify=True
@@ -150,7 +146,7 @@ class VirtualMachineTable(BaseTable):
         url_name='virtualization:virtualmachine_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VirtualMachine
         fields = (
             'pk', 'id', 'name', 'status', 'cluster', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
@@ -166,7 +162,6 @@ class VirtualMachineTable(BaseTable):
 #
 
 class VMInterfaceTable(BaseInterfaceTable):
-    pk = columns.ToggleColumn()
     virtual_machine = tables.Column(
         linkify=True
     )
@@ -177,7 +172,7 @@ class VMInterfaceTable(BaseInterfaceTable):
         url_name='virtualization:vminterface_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VMInterface
         fields = (
             'pk', 'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'mode', 'description', 'tags',
@@ -198,7 +193,7 @@ class VirtualMachineVMInterfaceTable(VMInterfaceTable):
         extra_buttons=VMINTERFACE_BUTTONS
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = VMInterface
         fields = (
             'pk', 'id', 'name', 'enabled', 'parent', 'bridge', 'mac_address', 'mtu', 'mode', 'description', 'tags',

+ 9 - 13
netbox/wireless/tables.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from dcim.models import Interface
-from netbox.tables import BaseTable, columns
+from netbox.tables import NetBoxTable, columns
 from .models import *
 
 __all__ = (
@@ -11,8 +11,7 @@ __all__ = (
 )
 
 
-class WirelessLANGroupTable(BaseTable):
-    pk = columns.ToggleColumn()
+class WirelessLANGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
         linkify=True
     )
@@ -25,7 +24,7 @@ class WirelessLANGroupTable(BaseTable):
         url_name='wireless:wirelesslangroup_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = WirelessLANGroup
         fields = (
             'pk', 'name', 'wirelesslan_count', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
@@ -33,8 +32,7 @@ class WirelessLANGroupTable(BaseTable):
         default_columns = ('pk', 'name', 'wirelesslan_count', 'description')
 
 
-class WirelessLANTable(BaseTable):
-    pk = columns.ToggleColumn()
+class WirelessLANTable(NetBoxTable):
     ssid = tables.Column(
         linkify=True
     )
@@ -48,7 +46,7 @@ class WirelessLANTable(BaseTable):
         url_name='wireless:wirelesslan_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = WirelessLAN
         fields = (
             'pk', 'ssid', 'group', 'description', 'vlan', 'interface_count', 'auth_type', 'auth_cipher', 'auth_psk',
@@ -57,8 +55,7 @@ class WirelessLANTable(BaseTable):
         default_columns = ('pk', 'ssid', 'group', 'description', 'vlan', 'auth_type', 'interface_count')
 
 
-class WirelessLANInterfacesTable(BaseTable):
-    pk = columns.ToggleColumn()
+class WirelessLANInterfacesTable(NetBoxTable):
     device = tables.Column(
         linkify=True
     )
@@ -66,14 +63,13 @@ class WirelessLANInterfacesTable(BaseTable):
         linkify=True
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = Interface
         fields = ('pk', 'device', 'name', 'rf_role', 'rf_channel')
         default_columns = ('pk', 'device', 'name', 'rf_role', 'rf_channel')
 
 
-class WirelessLinkTable(BaseTable):
-    pk = columns.ToggleColumn()
+class WirelessLinkTable(NetBoxTable):
     id = tables.Column(
         linkify=True,
         verbose_name='ID'
@@ -97,7 +93,7 @@ class WirelessLinkTable(BaseTable):
         url_name='wireless:wirelesslink_list'
     )
 
-    class Meta(BaseTable.Meta):
+    class Meta(NetBoxTable.Meta):
         model = WirelessLink
         fields = (
             'pk', 'id', 'status', 'device_a', 'interface_a', 'device_b', 'interface_b', 'ssid', 'description',