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

Closes #13150: Wrap table column headers with gettext()

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
Arthur Hanson 2 лет назад
Родитель
Сommit
e284cd7e54

+ 13 - 8
netbox/circuits/tables/circuits.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from circuits.models import *
@@ -24,7 +25,8 @@ CIRCUITTERMINATION_LINK = """
 
 class CircuitTypeTable(NetBoxTable):
     name = tables.Column(
-        linkify=True
+        linkify=True,
+        verbose_name=_('Name'),
     )
     tags = columns.TagColumn(
         url_name='circuits:circuittype_list'
@@ -32,7 +34,7 @@ class CircuitTypeTable(NetBoxTable):
     circuit_count = columns.LinkedCountColumn(
         viewname='circuits:circuit_list',
         url_params={'type_id': 'pk'},
-        verbose_name='Circuits'
+        verbose_name=_('Circuits')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -46,28 +48,31 @@ class CircuitTypeTable(NetBoxTable):
 class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     cid = tables.Column(
         linkify=True,
-        verbose_name='Circuit ID'
+        verbose_name=_('Circuit ID')
     )
     provider = tables.Column(
+        verbose_name=_('Provider'),
         linkify=True
     )
     provider_account = tables.Column(
         linkify=True,
-        verbose_name='Account'
+        verbose_name=_('Account')
     )
     status = columns.ChoiceFieldColumn()
     termination_a = tables.TemplateColumn(
         template_code=CIRCUITTERMINATION_LINK,
-        verbose_name='Side A'
+        verbose_name=_('Side A')
     )
     termination_z = tables.TemplateColumn(
         template_code=CIRCUITTERMINATION_LINK,
-        verbose_name='Side Z'
+        verbose_name=_('Side Z')
     )
     commit_rate = CommitRateColumn(
-        verbose_name='Commit Rate'
+        verbose_name=_('Commit Rate')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='circuits:circuit_list'
     )

+ 25 - 11
netbox/circuits/tables/providers.py

@@ -1,4 +1,5 @@
 import django_tables2 as tables
+from django.utils.translation import gettext_lazy as _
 from circuits.models import *
 from django_tables2.utils import Accessor
 from tenancy.tables import ContactsColumnMixin
@@ -14,35 +15,38 @@ __all__ = (
 
 class ProviderTable(ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     accounts = columns.ManyToManyColumn(
         linkify_item=True,
-        verbose_name='Accounts'
+        verbose_name=_('Accounts')
     )
     account_count = columns.LinkedCountColumn(
         accessor=tables.A('accounts__count'),
         viewname='circuits:provideraccount_list',
         url_params={'account_id': 'pk'},
-        verbose_name='Account Count'
+        verbose_name=_('Account Count')
     )
     asns = columns.ManyToManyColumn(
         linkify_item=True,
-        verbose_name='ASNs'
+        verbose_name=_('ASNs')
     )
     asn_count = columns.LinkedCountColumn(
         accessor=tables.A('asns__count'),
         viewname='ipam:asn_list',
         url_params={'provider_id': 'pk'},
-        verbose_name='ASN Count'
+        verbose_name=_('ASN Count')
     )
     circuit_count = columns.LinkedCountColumn(
         accessor=Accessor('count_circuits'),
         viewname='circuits:circuit_list',
         url_params={'provider_id': 'pk'},
-        verbose_name='Circuits'
+        verbose_name=_('Circuits')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='circuits:provider_list'
     )
@@ -58,19 +62,25 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
 
 class ProviderAccountTable(ContactsColumnMixin, NetBoxTable):
     account = tables.Column(
-        linkify=True
+        linkify=True,
+        verbose_name=_('Account'),
+    )
+    name = tables.Column(
+        verbose_name=_('Name'),
     )
-    name = tables.Column()
     provider = tables.Column(
+        verbose_name=_('Provider'),
         linkify=True
     )
     circuit_count = columns.LinkedCountColumn(
         accessor=Accessor('count_circuits'),
         viewname='circuits:circuit_list',
         url_params={'provider_account_id': 'pk'},
-        verbose_name='Circuits'
+        verbose_name=_('Circuits')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='circuits:provideraccount_list'
     )
@@ -86,12 +96,16 @@ class ProviderAccountTable(ContactsColumnMixin, NetBoxTable):
 
 class ProviderNetworkTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     provider = tables.Column(
+        verbose_name=_('Provider'),
         linkify=True
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='circuits:providernetwork_list'
     )

+ 16 - 4
netbox/core/tables/data.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from core.models import *
@@ -11,11 +12,18 @@ __all__ = (
 
 class DataSourceTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    type = columns.ChoiceFieldColumn()
-    status = columns.ChoiceFieldColumn()
-    enabled = columns.BooleanColumn()
+    type = columns.ChoiceFieldColumn(
+        verbose_name=_('Type'),
+    )
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
     tags = columns.TagColumn(
         url_name='core:datasource_list'
     )
@@ -34,12 +42,16 @@ class DataSourceTable(NetBoxTable):
 
 class DataFileTable(NetBoxTable):
     source = tables.Column(
+        verbose_name=_('Source'),
         linkify=True
     )
     path = tables.Column(
+        verbose_name=_('Path'),
         linkify=True
     )
-    last_updated = columns.DateTimeColumn()
+    last_updated = columns.DateTimeColumn(
+        verbose_name=_('Last updated'),
+    )
     actions = columns.ActionsColumn(
         actions=('delete',)
     )

+ 22 - 7
netbox/core/tables/jobs.py

@@ -1,5 +1,5 @@
 import django_tables2 as tables
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
 
 from netbox.tables import NetBoxTable, columns
 from ..models import Job
@@ -7,23 +7,38 @@ from ..models import Job
 
 class JobTable(NetBoxTable):
     id = tables.Column(
+        verbose_name=_('ID'),
         linkify=True
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     object_type = columns.ContentTypeColumn(
         verbose_name=_('Type')
     )
     object = tables.Column(
+        verbose_name=_('Object'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
-    created = columns.DateTimeColumn()
-    scheduled = columns.DateTimeColumn()
-    interval = columns.DurationColumn()
-    started = columns.DateTimeColumn()
-    completed = columns.DateTimeColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    created = columns.DateTimeColumn(
+        verbose_name=_('Created'),
+    )
+    scheduled = columns.DateTimeColumn(
+        verbose_name=_('Scheduled'),
+    )
+    interval = columns.DurationColumn(
+        verbose_name=_('Interval'),
+    )
+    started = columns.DateTimeColumn(
+        verbose_name=_('Started'),
+    )
+    completed = columns.DateTimeColumn(
+        verbose_name=_('Completed'),
+    )
     actions = columns.ActionsColumn(
         actions=('delete',)
     )

+ 11 - 10
netbox/dcim/tables/cables.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 from django.utils.safestring import mark_safe
@@ -50,60 +51,60 @@ class CableTable(TenancyColumnsMixin, NetBoxTable):
     a_terminations = CableTerminationsColumn(
         cable_end='A',
         orderable=False,
-        verbose_name='Termination A'
+        verbose_name=_('Termination A')
     )
     b_terminations = CableTerminationsColumn(
         cable_end='B',
         orderable=False,
-        verbose_name='Termination B'
+        verbose_name=_('Termination B')
     )
     device_a = CableTerminationsColumn(
         cable_end='A',
         attr='_device',
         orderable=False,
-        verbose_name='Device A'
+        verbose_name=_('Device A')
     )
     device_b = CableTerminationsColumn(
         cable_end='B',
         attr='_device',
         orderable=False,
-        verbose_name='Device B'
+        verbose_name=_('Device B')
     )
     location_a = CableTerminationsColumn(
         cable_end='A',
         attr='_location',
         orderable=False,
-        verbose_name='Location A'
+        verbose_name=_('Location A')
     )
     location_b = CableTerminationsColumn(
         cable_end='B',
         attr='_location',
         orderable=False,
-        verbose_name='Location B'
+        verbose_name=_('Location B')
     )
     rack_a = CableTerminationsColumn(
         cable_end='A',
         attr='_rack',
         orderable=False,
-        verbose_name='Rack A'
+        verbose_name=_('Rack A')
     )
     rack_b = CableTerminationsColumn(
         cable_end='B',
         attr='_rack',
         orderable=False,
-        verbose_name='Rack B'
+        verbose_name=_('Rack B')
     )
     site_a = CableTerminationsColumn(
         cable_end='A',
         attr='_site',
         orderable=False,
-        verbose_name='Site A'
+        verbose_name=_('Site A')
     )
     site_b = CableTerminationsColumn(
         cable_end='B',
         attr='_site',
         orderable=False,
-        verbose_name='Site B'
+        verbose_name=_('Site B')
     )
     status = columns.ChoiceFieldColumn()
     length = columns.TemplateColumn(

+ 10 - 5
netbox/dcim/tables/connections.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 
@@ -18,15 +19,16 @@ __all__ = (
 
 class ConsoleConnectionTable(PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     name = tables.Column(
         linkify=True,
-        verbose_name='Console Port'
+        verbose_name=_('Console Port')
     )
     reachable = columns.BooleanColumn(
         accessor=Accessor('_path__is_active'),
-        verbose_name='Reachable'
+        verbose_name=_('Reachable')
     )
 
     class Meta(BaseTable.Meta):
@@ -36,15 +38,16 @@ class ConsoleConnectionTable(PathEndpointTable):
 
 class PowerConnectionTable(PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     name = tables.Column(
         linkify=True,
-        verbose_name='Power Port'
+        verbose_name=_('Power Port')
     )
     reachable = columns.BooleanColumn(
         accessor=Accessor('_path__is_active'),
-        verbose_name='Reachable'
+        verbose_name=_('Reachable')
     )
 
     class Meta(BaseTable.Meta):
@@ -54,16 +57,18 @@ class PowerConnectionTable(PathEndpointTable):
 
 class InterfaceConnectionTable(PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         accessor=Accessor('device'),
         linkify=True
     )
     interface = tables.Column(
+        verbose_name=_('Interface'),
         accessor=Accessor('name'),
         linkify=True
     )
     reachable = columns.BooleanColumn(
         accessor=Accessor('_path__is_active'),
-        verbose_name='Reachable'
+        verbose_name=_('Reachable')
     )
 
     class Meta(BaseTable.Meta):

+ 136 - 49
netbox/dcim/tables/devices.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 from django.utils.translation import gettext as _
@@ -76,17 +77,18 @@ def get_interface_state_attribute(record):
 
 class DeviceRoleTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     device_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'role_id': 'pk'},
-        verbose_name='Devices'
+        verbose_name=_('Devices')
     )
     vm_count = columns.LinkedCountColumn(
         viewname='virtualization:virtualmachine_list',
         url_params={'role_id': 'pk'},
-        verbose_name='VMs'
+        verbose_name=_('VMs')
     )
     color = columns.ColorColumn()
     vm_role = columns.BooleanColumn()
@@ -112,23 +114,26 @@ class DeviceRoleTable(NetBoxTable):
 
 class PlatformTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         linkify=True
     )
     config_template = tables.Column(
+        verbose_name=_('Config Template'),
         linkify=True
     )
     device_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'platform_id': 'pk'},
-        verbose_name='Devices'
+        verbose_name=_('Devices')
     )
     vm_count = columns.LinkedCountColumn(
         viewname='virtualization:virtualmachine_list',
         url_params={'platform_id': 'pk'},
-        verbose_name='VMs'
+        verbose_name=_('VMs')
     )
     tags = columns.TagColumn(
         url_name='dcim:platform_list'
@@ -151,82 +156,94 @@ class PlatformTable(NetBoxTable):
 
 class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         order_by=('_name',),
         template_code=DEVICE_LINK,
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     region = tables.Column(
+        verbose_name=_('Region'),
         accessor=Accessor('site__region'),
         linkify=True
     )
     site_group = tables.Column(
         accessor=Accessor('site__group'),
         linkify=True,
-        verbose_name='Site Group'
+        verbose_name=_('Site Group')
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     location = tables.Column(
+        verbose_name=_('Location'),
         linkify=True
     )
     rack = tables.Column(
+        verbose_name=_('Rack'),
         linkify=True
     )
     position = columns.TemplateColumn(
+        verbose_name=_('Position'),
         template_code='{{ value|floatformat }}'
     )
     device_role = columns.ColoredLabelColumn(
-        verbose_name='Role'
+        verbose_name=_('Role')
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         accessor=Accessor('device_type__manufacturer'),
         linkify=True
     )
     device_type = tables.Column(
         linkify=True,
-        verbose_name='Type'
+        verbose_name=_('Type')
     )
     primary_ip = tables.Column(
         linkify=True,
         order_by=('primary_ip4', 'primary_ip6'),
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
     )
     primary_ip4 = tables.Column(
         linkify=True,
-        verbose_name='IPv4 Address'
+        verbose_name=_('IPv4 Address')
     )
     primary_ip6 = tables.Column(
         linkify=True,
-        verbose_name='IPv6 Address'
+        verbose_name=_('IPv6 Address')
     )
     oob_ip = tables.Column(
         linkify=True,
         verbose_name='OOB IP'
     )
     cluster = tables.Column(
+        verbose_name=_('Cluster'),
         linkify=True
     )
     virtual_chassis = tables.Column(
+        verbose_name=_('Virtual Chassis'),
         linkify=True
     )
     vc_position = tables.Column(
-        verbose_name='VC Position'
+        verbose_name=_('VC Position')
     )
     vc_priority = tables.Column(
-        verbose_name='VC Priority'
+        verbose_name=_('VC Priority')
     )
     config_template = tables.Column(
+        verbose_name=_('Config Template'),
         linkify=True
     )
     parent_device = tables.Column(
-        verbose_name='Parent Device',
+        verbose_name=_('Parent Device'),
         linkify=True,
         accessor='parent_bay__device'
     )
     device_bay_position = tables.Column(
-        verbose_name='Position (Device Bay)',
+        verbose_name=_('Position (Device Bay)'),
         accessor='parent_bay',
         linkify=True
     )
@@ -282,21 +299,26 @@ class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
 
 class DeviceImportTable(TenancyColumnsMixin, NetBoxTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code=DEVICE_LINK,
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     rack = tables.Column(
+        verbose_name=_('Rack'),
         linkify=True
     )
     device_role = tables.Column(
-        verbose_name='Role'
+        verbose_name=_('Role')
     )
     device_type = tables.Column(
-        verbose_name='Type'
+        verbose_name=_('Type')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -311,9 +333,11 @@ class DeviceImportTable(TenancyColumnsMixin, NetBoxTable):
 
 class DeviceComponentTable(NetBoxTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True,
         order_by=('_name',)
     )
@@ -324,6 +348,7 @@ class DeviceComponentTable(NetBoxTable):
 
 class ModularDeviceComponentTable(DeviceComponentTable):
     module_bay = tables.Column(
+        verbose_name=_('Module Bay'),
         accessor=Accessor('module__module_bay'),
         linkify={
             'viewname': 'dcim:device_modulebays',
@@ -331,39 +356,44 @@ class ModularDeviceComponentTable(DeviceComponentTable):
         }
     )
     module = tables.Column(
+        verbose_name=_('Module'),
         linkify=True
     )
 
 
 class CableTerminationTable(NetBoxTable):
     cable = tables.Column(
+        verbose_name=_('Cable'),
         linkify=True
     )
     cable_color = columns.ColorColumn(
         accessor='cable__color',
         orderable=False,
-        verbose_name='Cable Color'
+        verbose_name=_('Cable Color')
     )
     link_peer = columns.TemplateColumn(
         accessor='link_peers',
         template_code=LINKTERMINATION,
         orderable=False,
-        verbose_name='Link Peers'
+        verbose_name=_('Link Peers')
+    )
+    mark_connected = columns.BooleanColumn(
+        verbose_name=_('Mark Connected'),
     )
-    mark_connected = columns.BooleanColumn()
 
 
 class PathEndpointTable(CableTerminationTable):
     connection = columns.TemplateColumn(
         accessor='_path__destinations',
         template_code=LINKTERMINATION,
-        verbose_name='Connection',
+        verbose_name=_('Connection'),
         orderable=False
     )
 
 
 class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_consoleports',
             'args': [Accessor('device_id')],
@@ -384,6 +414,7 @@ class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable):
 
 class DeviceConsolePortTable(ConsolePortTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-console"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
         attrs={'td': {'class': 'text-nowrap'}}
@@ -406,6 +437,7 @@ class DeviceConsolePortTable(ConsolePortTable):
 
 class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_consoleserverports',
             'args': [Accessor('device_id')],
@@ -426,6 +458,7 @@ class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable):
 
 class DeviceConsoleServerPortTable(ConsoleServerPortTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-console-network-outline"></i> '
                       '<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -449,6 +482,7 @@ class DeviceConsoleServerPortTable(ConsoleServerPortTable):
 
 class PowerPortTable(ModularDeviceComponentTable, PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_powerports',
             'args': [Accessor('device_id')],
@@ -470,6 +504,7 @@ class PowerPortTable(ModularDeviceComponentTable, PathEndpointTable):
 
 class DevicePowerPortTable(PowerPortTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-power-plug-outline"></i> <a href="{{ record.get_absolute_url }}">'
                       '{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -495,12 +530,14 @@ class DevicePowerPortTable(PowerPortTable):
 
 class PowerOutletTable(ModularDeviceComponentTable, PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_poweroutlets',
             'args': [Accessor('device_id')],
         }
     )
     power_port = tables.Column(
+        verbose_name=_('Power Port'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -519,6 +556,7 @@ class PowerOutletTable(ModularDeviceComponentTable, PathEndpointTable):
 
 class DevicePowerOutletTable(PowerOutletTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-power-socket"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
         attrs={'td': {'class': 'text-nowrap'}}
@@ -542,29 +580,34 @@ class DevicePowerOutletTable(PowerOutletTable):
 
 
 class BaseInterfaceTable(NetBoxTable):
-    enabled = columns.BooleanColumn()
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
     ip_addresses = tables.TemplateColumn(
         template_code=INTERFACE_IPADDRESSES,
         orderable=False,
-        verbose_name='IP Addresses'
+        verbose_name=_('IP Addresses')
     )
     fhrp_groups = tables.TemplateColumn(
         accessor=Accessor('fhrp_group_assignments'),
         template_code=INTERFACE_FHRPGROUPS,
         orderable=False,
-        verbose_name='FHRP Groups'
+        verbose_name=_('FHRP Groups')
     )
     l2vpn = tables.Column(
         accessor=tables.A('l2vpn_termination__l2vpn'),
         linkify=True,
         orderable=False,
-        verbose_name='L2VPN'
+        verbose_name=_('L2VPN')
+    )
+    untagged_vlan = tables.Column(
+        verbose_name=_('Untagged VLAN'),
+        linkify=True
     )
-    untagged_vlan = tables.Column(linkify=True)
     tagged_vlans = columns.TemplateColumn(
         template_code=INTERFACE_TAGGED_VLANS,
         orderable=False,
-        verbose_name='Tagged VLANs'
+        verbose_name=_('Tagged VLANs')
     )
 
     def value_ip_addresses(self, value):
@@ -573,25 +616,30 @@ class BaseInterfaceTable(NetBoxTable):
 
 class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpointTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_interfaces',
             'args': [Accessor('device_id')],
         }
     )
-    mgmt_only = columns.BooleanColumn()
+    mgmt_only = columns.BooleanColumn(
+        verbose_name=_('Management Only'),
+    )
     wireless_link = tables.Column(
+        verbose_name=_('Wireless link'),
         linkify=True
     )
     wireless_lans = columns.TemplateColumn(
         template_code=INTERFACE_WIRELESS_LANS,
         orderable=False,
-        verbose_name='Wireless LANs'
+        verbose_name=_('Wireless LANs')
     )
     vdcs = columns.ManyToManyColumn(
         linkify_item=True,
-        verbose_name='VDCs'
+        verbose_name=_('VDCs')
     )
     vrf = tables.Column(
+        verbose_name=_('VRF'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -612,6 +660,7 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
 
 class DeviceInterfaceTable(InterfaceTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-{% if record.mgmt_only %}wrench{% elif record.is_lag %}reorder-horizontal'
                       '{% elif record.is_virtual %}circle{% elif record.is_wireless %}wifi{% else %}ethernet'
                       '{% endif %}"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
@@ -619,14 +668,16 @@ class DeviceInterfaceTable(InterfaceTable):
         attrs={'td': {'class': 'text-nowrap'}}
     )
     parent = tables.Column(
+        verbose_name=_('Parent'),
         linkify=True
     )
     bridge = tables.Column(
+        verbose_name=_('Bridge'),
         linkify=True
     )
     lag = tables.Column(
         linkify=True,
-        verbose_name='LAG'
+        verbose_name=_('LAG')
     )
     actions = columns.ActionsColumn(
         extra_buttons=INTERFACE_BUTTONS
@@ -655,16 +706,20 @@ class DeviceInterfaceTable(InterfaceTable):
 
 class FrontPortTable(ModularDeviceComponentTable, CableTerminationTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_frontports',
             'args': [Accessor('device_id')],
         }
     )
-    color = columns.ColorColumn()
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
+    )
     rear_port_position = tables.Column(
-        verbose_name='Position'
+        verbose_name=_('Position')
     )
     rear_port = tables.Column(
+        verbose_name=_('Rear Port'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -685,6 +740,7 @@ class FrontPortTable(ModularDeviceComponentTable, CableTerminationTable):
 
 class DeviceFrontPortTable(FrontPortTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-square-rounded{% if not record.cable %}-outline{% endif %}"></i> '
                       '<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -710,12 +766,15 @@ class DeviceFrontPortTable(FrontPortTable):
 
 class RearPortTable(ModularDeviceComponentTable, CableTerminationTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_rearports',
             'args': [Accessor('device_id')],
         }
     )
-    color = columns.ColorColumn()
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
+    )
     tags = columns.TagColumn(
         url_name='dcim:rearport_list'
     )
@@ -731,6 +790,7 @@ class RearPortTable(ModularDeviceComponentTable, CableTerminationTable):
 
 class DeviceRearPortTable(RearPortTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-square-rounded{% if not record.cable %}-outline{% endif %}"></i> '
                       '<a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -756,6 +816,7 @@ class DeviceRearPortTable(RearPortTable):
 
 class DeviceBayTable(DeviceComponentTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_devicebays',
             'args': [Accessor('device_id')],
@@ -763,18 +824,20 @@ class DeviceBayTable(DeviceComponentTable):
     )
     device_role = columns.ColoredLabelColumn(
         accessor=Accessor('installed_device__device_role'),
-        verbose_name='Role'
+        verbose_name=_('Role')
     )
     device_type = tables.Column(
         accessor=Accessor('installed_device__device_type'),
         linkify=True,
-        verbose_name='Type'
+        verbose_name=_('Type')
     )
     status = tables.TemplateColumn(
+        verbose_name=_('Status'),
         template_code=DEVICEBAY_STATUS,
         order_by=Accessor('installed_device__status')
     )
     installed_device = tables.Column(
+        verbose_name=_('Installed device'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -793,6 +856,7 @@ class DeviceBayTable(DeviceComponentTable):
 
 class DeviceDeviceBayTable(DeviceBayTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<i class="mdi mdi-circle{% if record.installed_device %}slice-8{% else %}outline{% endif %}'
                       '"></i> <a href="{{ record.get_absolute_url }}">{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -812,6 +876,7 @@ class DeviceDeviceBayTable(DeviceBayTable):
 
 class ModuleBayTable(DeviceComponentTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_modulebays',
             'args': [Accessor('device_id')],
@@ -819,18 +884,21 @@ class ModuleBayTable(DeviceComponentTable):
     )
     installed_module = tables.Column(
         linkify=True,
-        verbose_name='Installed module'
+        verbose_name=_('Installed Module')
     )
     module_serial = tables.Column(
+        verbose_name=_('Module Serial'),
         accessor=tables.A('installed_module__serial')
     )
     module_asset_tag = tables.Column(
+        verbose_name=_('Module Asset Tag'),
         accessor=tables.A('installed_module__asset_tag')
     )
     tags = columns.TagColumn(
         url_name='dcim:modulebay_list'
     )
     module_status = columns.TemplateColumn(
+        verbose_name=_('Module Status'),
         template_code=MODULEBAY_STATUS
     )
 
@@ -859,20 +927,27 @@ class DeviceModuleBayTable(ModuleBayTable):
 
 class InventoryItemTable(DeviceComponentTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify={
             'viewname': 'dcim:device_inventory',
             'args': [Accessor('device_id')],
         }
     )
-    role = columns.ColoredLabelColumn()
+    role = columns.ColoredLabelColumn(
+        verbose_name=_('Role'),
+    )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         linkify=True
     )
     component = tables.Column(
+        verbose_name=_('Component'),
         orderable=False,
         linkify=True
     )
-    discovered = columns.BooleanColumn()
+    discovered = columns.BooleanColumn(
+        verbose_name=_('Discovered'),
+    )
     tags = columns.TagColumn(
         url_name='dcim:inventoryitem_list'
     )
@@ -891,6 +966,7 @@ class InventoryItemTable(DeviceComponentTable):
 
 class DeviceInventoryItemTable(InventoryItemTable):
     name = tables.TemplateColumn(
+        verbose_name=_('Name'),
         template_code='<a href="{{ record.get_absolute_url }}" style="padding-left: {{ record.level }}0px">'
                       '{{ value }}</a>',
         order_by=Accessor('_name'),
@@ -910,14 +986,17 @@ class DeviceInventoryItemTable(InventoryItemTable):
 
 class InventoryItemRoleTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     inventoryitem_count = columns.LinkedCountColumn(
         viewname='dcim:inventoryitem_list',
         url_params={'role_id': 'pk'},
-        verbose_name='Items'
+        verbose_name=_('Items')
+    )
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
     )
-    color = columns.ColorColumn()
     tags = columns.TagColumn(
         url_name='dcim:inventoryitemrole_list'
     )
@@ -936,17 +1015,21 @@ class InventoryItemRoleTable(NetBoxTable):
 
 class VirtualChassisTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     master = tables.Column(
+        verbose_name=_('Master'),
         linkify=True
     )
     member_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'virtual_chassis_id': 'pk'},
-        verbose_name='Members'
+        verbose_name=_('Members')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:virtualchassis_list'
     )
@@ -962,31 +1045,35 @@ class VirtualChassisTable(NetBoxTable):
 
 class VirtualDeviceContextTable(TenancyColumnsMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     device = tables.TemplateColumn(
+        verbose_name=_('Device'),
         order_by=('_name',),
         template_code=DEVICE_LINK,
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     primary_ip = tables.Column(
         linkify=True,
         order_by=('primary_ip4', 'primary_ip6'),
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
     )
     primary_ip4 = tables.Column(
         linkify=True,
-        verbose_name='IPv4 Address'
+        verbose_name=_('IPv4 Address')
     )
     primary_ip6 = tables.Column(
         linkify=True,
-        verbose_name='IPv6 Address'
+        verbose_name=_('IPv6 Address')
     )
     interface_count = columns.LinkedCountColumn(
         viewname='dcim:interface_list',
         url_params={'vdc_id': 'pk'},
-        verbose_name='Interfaces'
+        verbose_name=_('Interfaces')
     )
 
     comments = columns.MarkdownColumn()

+ 40 - 23
netbox/dcim/tables/devicetypes.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django.utils.translation import gettext as _
 
@@ -28,27 +29,28 @@ __all__ = (
 
 class ManufacturerTable(ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     devicetype_count = columns.LinkedCountColumn(
         viewname='dcim:devicetype_list',
         url_params={'manufacturer_id': 'pk'},
-        verbose_name='Device Types'
+        verbose_name=_('Device Types')
     )
     moduletype_count = columns.LinkedCountColumn(
         viewname='dcim:moduletype_list',
         url_params={'manufacturer_id': 'pk'},
-        verbose_name='Module Types'
+        verbose_name=_('Module Types')
     )
     inventoryitem_count = columns.LinkedCountColumn(
         viewname='dcim:inventoryitem_list',
         url_params={'manufacturer_id': 'pk'},
-        verbose_name='Inventory Items'
+        verbose_name=_('Inventory Items')
     )
     platform_count = columns.LinkedCountColumn(
         viewname='dcim:platform_list',
         url_params={'manufacturer_id': 'pk'},
-        verbose_name='Platforms'
+        verbose_name=_('Platforms')
     )
     tags = columns.TagColumn(
         url_name='dcim:manufacturer_list'
@@ -73,62 +75,68 @@ class ManufacturerTable(ContactsColumnMixin, NetBoxTable):
 class DeviceTypeTable(NetBoxTable):
     model = tables.Column(
         linkify=True,
-        verbose_name='Device Type'
+        verbose_name=_('Device Type')
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         linkify=True
     )
     default_platform = tables.Column(
+        verbose_name=_('Default Platform'),
         linkify=True
     )
     is_full_depth = columns.BooleanColumn(
-        verbose_name='Full Depth'
+        verbose_name=_('Full Depth')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:devicetype_list'
     )
     u_height = columns.TemplateColumn(
+        verbose_name=_('U Height'),
         template_code='{{ value|floatformat }}'
     )
     weight = columns.TemplateColumn(
+        verbose_name=_('Weight'),
         template_code=WEIGHT,
         order_by=('_abs_weight', 'weight_unit')
     )
     instance_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'device_type_id': 'pk'},
-        verbose_name='Instances'
+        verbose_name=_('Instances')
     )
     console_port_template_count = tables.Column(
-        verbose_name=_('Console ports')
+        verbose_name=_('Console Ports')
     )
     console_server_port_template_count = tables.Column(
-        verbose_name=_('Console server ports')
+        verbose_name=_('Console Server Ports')
     )
     power_port_template_count = tables.Column(
-        verbose_name=_('Power ports')
+        verbose_name=_('Power Ports')
     )
     power_outlet_template_count = tables.Column(
-        verbose_name=_('Power outlets')
+        verbose_name=_('Power Outlets')
     )
     interface_template_count = tables.Column(
         verbose_name=_('Interfaces')
     )
     front_port_template_count = tables.Column(
-        verbose_name=_('Front ports')
+        verbose_name=_('Front Ports')
     )
     rear_port_template_count = tables.Column(
-        verbose_name=_('Rear ports')
+        verbose_name=_('Rear Ports')
     )
     device_bay_template_count = tables.Column(
-        verbose_name=_('Device bays')
+        verbose_name=_('Device Bays')
     )
     module_bay_template_count = tables.Column(
-        verbose_name=_('Module bays')
+        verbose_name=_('Module Bays')
     )
     inventory_item_template_count = tables.Column(
-        verbose_name=_('Inventory items')
+        verbose_name=_('Inventory Items')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -149,7 +157,7 @@ class DeviceTypeTable(NetBoxTable):
 
 class ComponentTemplateTable(NetBoxTable):
     id = tables.Column(
-        verbose_name='ID'
+        verbose_name=_('ID')
     )
     name = tables.Column(
         order_by=('_name',)
@@ -208,9 +216,11 @@ class PowerOutletTemplateTable(ComponentTemplateTable):
 
 
 class InterfaceTemplateTable(ComponentTemplateTable):
-    enabled = columns.BooleanColumn()
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
     mgmt_only = columns.BooleanColumn(
-        verbose_name='Management Only'
+        verbose_name=_('Management Only')
     )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
@@ -228,9 +238,11 @@ class InterfaceTemplateTable(ComponentTemplateTable):
 
 class FrontPortTemplateTable(ComponentTemplateTable):
     rear_port_position = tables.Column(
-        verbose_name='Position'
+        verbose_name=_('Position')
+    )
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
     )
-    color = columns.ColorColumn()
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
         extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
@@ -243,7 +255,9 @@ class FrontPortTemplateTable(ComponentTemplateTable):
 
 
 class RearPortTemplateTable(ComponentTemplateTable):
-    color = columns.ColorColumn()
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
+    )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
         extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
@@ -282,12 +296,15 @@ class InventoryItemTemplateTable(ComponentTemplateTable):
         actions=('edit', 'delete')
     )
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         linkify=True
     )
     component = tables.Column(
+        verbose_name=_('Component'),
         orderable=False
     )
 

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

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from dcim.models import Module, ModuleType
@@ -13,21 +14,25 @@ __all__ = (
 class ModuleTypeTable(NetBoxTable):
     model = tables.Column(
         linkify=True,
-        verbose_name='Module Type'
+        verbose_name=_('Module Type')
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         linkify=True
     )
     instance_count = columns.LinkedCountColumn(
         viewname='dcim:module_list',
         url_params={'module_type_id': 'pk'},
-        verbose_name='Instances'
+        verbose_name=_('Instances')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:moduletype_list'
     )
     weight = columns.TemplateColumn(
+        verbose_name=_('Weight'),
         template_code=WEIGHT,
         order_by=('_abs_weight', 'weight_unit')
     )
@@ -44,20 +49,28 @@ class ModuleTypeTable(NetBoxTable):
 
 class ModuleTable(NetBoxTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     module_bay = tables.Column(
+        verbose_name=_('Module Bay'),
         linkify=True
     )
     manufacturer = tables.Column(
+        verbose_name=_('Manufacturer'),
         accessor=tables.A('module_type__manufacturer'),
         linkify=True
     )
     module_type = tables.Column(
+        verbose_name=_('Module Type'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
-    comments = columns.MarkdownColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='dcim:module_list'
     )

+ 24 - 7
netbox/dcim/tables/power.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from dcim.models import PowerFeed, PowerPanel
 from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
@@ -18,20 +19,25 @@ __all__ = (
 
 class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     location = tables.Column(
+        verbose_name=_('Location'),
         linkify=True
     )
     powerfeed_count = columns.LinkedCountColumn(
         viewname='dcim:powerfeed_list',
         url_params={'power_panel_id': 'pk'},
-        verbose_name='Feeds'
+        verbose_name=_('Power Feeds')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:powerpanel_list'
     )
@@ -53,26 +59,37 @@ class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
 # cannot traverse pass-through ports.
 class PowerFeedTable(TenancyColumnsMixin, CableTerminationTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     power_panel = tables.Column(
+        verbose_name=_('Power Panel'),
         linkify=True
     )
     rack = tables.Column(
+        verbose_name=_('Rack'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
-    type = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    type = columns.ChoiceFieldColumn(
+        verbose_name=_('Type'),
+    )
     max_utilization = tables.TemplateColumn(
+        verbose_name=_('Max Utilization'),
         template_code="{{ value }}%"
     )
     available_power = tables.Column(
-        verbose_name='Available power (VA)'
+        verbose_name=_('Available Power (VA)')
     )
     tenant = tables.Column(
-        linkify=True
+        linkify=True,
+        verbose_name=_('Tenant')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:powerfeed_list'
     )

+ 37 - 14
netbox/dcim/tables/racks.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 
@@ -18,13 +19,18 @@ __all__ = (
 #
 
 class RackRoleTable(NetBoxTable):
-    name = tables.Column(linkify=True)
+    name = tables.Column(
+        verbose_name=_('Name'),
+        linkify=True
+    )
     rack_count = columns.LinkedCountColumn(
         viewname='dcim:rack_list',
         url_params={'role_id': 'pk'},
-        verbose_name='Racks'
+        verbose_name=_('Racks')
+    )
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
     )
-    color = columns.ColorColumn()
     tags = columns.TagColumn(
         url_name='dcim:rackrole_list'
     )
@@ -44,51 +50,62 @@ class RackRoleTable(NetBoxTable):
 
 class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         order_by=('_name',),
         linkify=True
     )
     location = tables.Column(
+        verbose_name=_('Location'),
         linkify=True
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
-    role = columns.ColoredLabelColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    role = columns.ColoredLabelColumn(
+        verbose_name=_('Role'),
+    )
     u_height = tables.TemplateColumn(
         template_code="{{ value }}U",
-        verbose_name='Height'
+        verbose_name=_('Height')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     device_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'rack_id': 'pk'},
-        verbose_name='Devices'
+        verbose_name=_('Devices')
     )
     get_utilization = columns.UtilizationColumn(
         orderable=False,
-        verbose_name='Space'
+        verbose_name=_('Space')
     )
     get_power_utilization = columns.UtilizationColumn(
         orderable=False,
-        verbose_name='Power'
+        verbose_name=_('Power')
     )
     tags = columns.TagColumn(
         url_name='dcim:rack_list'
     )
     outer_width = tables.TemplateColumn(
         template_code="{{ record.outer_width }} {{ record.outer_unit }}",
-        verbose_name='Outer Width'
+        verbose_name=_('Outer Width')
     )
     outer_depth = tables.TemplateColumn(
         template_code="{{ record.outer_depth }} {{ record.outer_unit }}",
-        verbose_name='Outer Depth'
+        verbose_name=_('Outer Depth')
     )
     weight = columns.TemplateColumn(
+        verbose_name=_('Weight'),
         template_code=WEIGHT,
         order_by=('_abs_weight', 'weight_unit')
     )
     max_weight = columns.TemplateColumn(
+        verbose_name=_('Max Weight'),
         template_code=WEIGHT,
         order_by=('_abs_max_weight', 'weight_unit')
     )
@@ -113,25 +130,31 @@ class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
 
 class RackReservationTable(TenancyColumnsMixin, NetBoxTable):
     reservation = tables.Column(
+        verbose_name=_('Reservation'),
         accessor='pk',
         linkify=True
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         accessor=Accessor('rack__site'),
         linkify=True
     )
     location = tables.Column(
+        verbose_name=_('Location'),
         accessor=Accessor('rack__location'),
         linkify=True
     )
     rack = tables.Column(
+        verbose_name=_('Rack'),
         linkify=True
     )
     unit_list = tables.Column(
         orderable=False,
-        verbose_name='Units'
+        verbose_name=_('Units')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:rackreservation_list'
     )

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

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from dcim.models import Location, Region, Site, SiteGroup
 from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
@@ -20,12 +21,13 @@ __all__ = (
 
 class RegionTable(ContactsColumnMixin, NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     site_count = columns.LinkedCountColumn(
         viewname='dcim:site_list',
         url_params={'region_id': 'pk'},
-        verbose_name='Sites'
+        verbose_name=_('Sites')
     )
     tags = columns.TagColumn(
         url_name='dcim:region_list'
@@ -46,12 +48,13 @@ class RegionTable(ContactsColumnMixin, NetBoxTable):
 
 class SiteGroupTable(ContactsColumnMixin, NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     site_count = columns.LinkedCountColumn(
         viewname='dcim:site_list',
         url_params={'group_id': 'pk'},
-        verbose_name='Sites'
+        verbose_name=_('Sites')
     )
     tags = columns.TagColumn(
         url_name='dcim:sitegroup_list'
@@ -72,26 +75,33 @@ class SiteGroupTable(ContactsColumnMixin, NetBoxTable):
 
 class SiteTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     region = tables.Column(
+        verbose_name=_('Region'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
     asns = columns.ManyToManyColumn(
         linkify_item=True,
-        verbose_name='ASNs'
+        verbose_name=_('ASNs')
     )
     asn_count = columns.LinkedCountColumn(
         accessor=tables.A('asns__count'),
         viewname='ipam:asn_list',
         url_params={'site_id': 'pk'},
-        verbose_name='ASN Count'
+        verbose_name=_('ASN Count')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='dcim:site_list'
     )
@@ -112,21 +122,25 @@ class SiteTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
 
 class LocationTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     rack_count = columns.LinkedCountColumn(
         viewname='dcim:rack_list',
         url_params={'location_id': 'pk'},
-        verbose_name='Racks'
+        verbose_name=_('Racks')
     )
     device_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'location_id': 'pk'},
-        verbose_name='Devices'
+        verbose_name=_('Devices')
     )
     tags = columns.TagColumn(
         url_name='dcim:location_list'

+ 120 - 49
netbox/extras/tables/tables.py

@@ -2,7 +2,7 @@ import json
 
 import django_tables2 as tables
 from django.conf import settings
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
 
 from extras.models import *
 from netbox.tables import NetBoxTable, columns
@@ -44,7 +44,9 @@ REVISION_BUTTONS = """
 
 
 class ConfigRevisionTable(NetBoxTable):
-    is_active = columns.BooleanColumn()
+    is_active = columns.BooleanColumn(
+        verbose_name=_('Is Active'),
+    )
     actions = columns.ActionsColumn(
         actions=('delete',),
         extra_buttons=REVISION_BUTTONS
@@ -60,20 +62,33 @@ class ConfigRevisionTable(NetBoxTable):
 
 class CustomFieldTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    content_types = columns.ContentTypesColumn()
-    required = columns.BooleanColumn()
-    ui_visibility = columns.ChoiceFieldColumn(verbose_name="UI visibility")
-    description = columns.MarkdownColumn()
+    content_types = columns.ContentTypesColumn(
+        verbose_name=_('Content Types')
+    )
+    required = columns.BooleanColumn(
+        verbose_name=_('Required')
+    )
+    ui_visibility = columns.ChoiceFieldColumn(
+        verbose_name=_('UI Visibility')
+    )
+    description = columns.MarkdownColumn(
+        verbose_name=_('Description')
+    )
     choice_set = tables.Column(
-        linkify=True
+        linkify=True,
+        verbose_name=_('Choice Set')
     )
     choices = columns.ChoicesColumn(
         max_items=10,
-        orderable=False
+        orderable=False,
+        verbose_name=_('Choices')
+    )
+    is_cloneable = columns.BooleanColumn(
+        verbose_name=_('Is Cloneable'),
     )
-    is_cloneable = columns.BooleanColumn()
 
     class Meta(NetBoxTable.Meta):
         model = CustomField
@@ -87,6 +102,7 @@ class CustomFieldTable(NetBoxTable):
 
 class CustomFieldChoiceSetTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     base_choices = columns.ChoiceFieldColumn()
@@ -103,7 +119,9 @@ class CustomFieldChoiceSetTable(NetBoxTable):
         orderable=False,
         verbose_name=_('Count')
     )
-    order_alphabetically = columns.BooleanColumn()
+    order_alphabetically = columns.BooleanColumn(
+        verbose_name=_('Order Alphabetically'),
+    )
 
     class Meta(NetBoxTable.Meta):
         model = CustomFieldChoiceSet
@@ -116,11 +134,18 @@ class CustomFieldChoiceSetTable(NetBoxTable):
 
 class CustomLinkTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    content_types = columns.ContentTypesColumn()
-    enabled = columns.BooleanColumn()
-    new_window = columns.BooleanColumn()
+    content_types = columns.ContentTypesColumn(
+        verbose_name=_('Content Types'),
+    )
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
+    new_window = columns.BooleanColumn(
+        verbose_name=_('New Window'),
+    )
 
     class Meta(NetBoxTable.Meta):
         model = CustomLink
@@ -133,19 +158,26 @@ class CustomLinkTable(NetBoxTable):
 
 class ExportTemplateTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    content_types = columns.ContentTypesColumn()
-    as_attachment = columns.BooleanColumn()
+    content_types = columns.ContentTypesColumn(
+        verbose_name=_('Content Types'),
+    )
+    as_attachment = columns.BooleanColumn(
+        verbose_name=_('As Attachment'),
+    )
     data_source = tables.Column(
+        verbose_name=_('Data Source'),
         linkify=True
     )
     data_file = tables.Column(
+        verbose_name=_('Data File'),
         linkify=True
     )
     is_synced = columns.BooleanColumn(
         orderable=False,
-        verbose_name='Synced'
+        verbose_name=_('Synced')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -161,18 +193,23 @@ class ExportTemplateTable(NetBoxTable):
 
 class ImageAttachmentTable(NetBoxTable):
     id = tables.Column(
+        verbose_name=_('ID'),
         linkify=False
     )
-    content_type = columns.ContentTypeColumn()
+    content_type = columns.ContentTypeColumn(
+        verbose_name=_('Content Type'),
+    )
     parent = tables.Column(
+        verbose_name=_('Parent'),
         linkify=True
     )
     image = tables.TemplateColumn(
+        verbose_name=_('Image'),
         template_code=IMAGEATTACHMENT_IMAGE,
     )
     size = tables.Column(
         orderable=False,
-        verbose_name='Size (bytes)'
+        verbose_name=_('Size (Bytes)')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -186,11 +223,18 @@ class ImageAttachmentTable(NetBoxTable):
 
 class SavedFilterTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    content_types = columns.ContentTypesColumn()
-    enabled = columns.BooleanColumn()
-    shared = columns.BooleanColumn()
+    content_types = columns.ContentTypesColumn(
+        verbose_name=_('Content Types'),
+    )
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
+    shared = columns.BooleanColumn(
+        verbose_name=_('Shared'),
+    )
 
     def value_parameters(self, value):
         return json.dumps(value)
@@ -207,8 +251,11 @@ class SavedFilterTable(NetBoxTable):
 
 
 class BookmarkTable(NetBoxTable):
-    object_type = columns.ContentTypeColumn()
+    object_type = columns.ContentTypeColumn(
+        verbose_name=_('Object Types'),
+    )
     object = tables.Column(
+        verbose_name=_('Object'),
         linkify=True
     )
     actions = columns.ActionsColumn(
@@ -223,27 +270,32 @@ class BookmarkTable(NetBoxTable):
 
 class WebhookTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    content_types = columns.ContentTypesColumn()
-    enabled = columns.BooleanColumn()
+    content_types = columns.ContentTypesColumn(
+        verbose_name=_('Content Types'),
+    )
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
     type_create = columns.BooleanColumn(
-        verbose_name='Create'
+        verbose_name=_('Create')
     )
     type_update = columns.BooleanColumn(
-        verbose_name='Update'
+        verbose_name=_('Update')
     )
     type_delete = columns.BooleanColumn(
-        verbose_name='Delete'
+        verbose_name=_('Delete')
     )
     type_job_start = columns.BooleanColumn(
-        verbose_name='Job start'
+        verbose_name=_('Job Start')
     )
     type_job_end = columns.BooleanColumn(
-        verbose_name='Job end'
+        verbose_name=_('Job End')
     )
     ssl_validation = columns.BooleanColumn(
-        verbose_name='SSL Validation'
+        verbose_name=_('SSL Validation')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -261,10 +313,15 @@ class WebhookTable(NetBoxTable):
 
 class TagTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    color = columns.ColorColumn()
-    object_types = columns.ContentTypesColumn()
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
+    )
+    object_types = columns.ContentTypesColumn(
+        verbose_name=_('Object Types'),
+    )
 
     class Meta(NetBoxTable.Meta):
         model = Tag
@@ -277,17 +334,17 @@ class TagTable(NetBoxTable):
 
 class TaggedItemTable(NetBoxTable):
     id = tables.Column(
-        verbose_name='ID',
+        verbose_name=_('ID'),
         linkify=lambda record: record.content_object.get_absolute_url(),
         accessor='content_object__id'
     )
     content_type = columns.ContentTypeColumn(
-        verbose_name='Type'
+        verbose_name=_('Type')
     )
     content_object = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Object'
+        verbose_name=_('Object')
     )
     actions = columns.ActionsColumn(
         actions=()
@@ -300,20 +357,23 @@ class TaggedItemTable(NetBoxTable):
 
 class ConfigContextTable(NetBoxTable):
     data_source = tables.Column(
+        verbose_name=_('Data Source'),
         linkify=True
     )
     data_file = tables.Column(
+        verbose_name=_('Data File'),
         linkify=True
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     is_active = columns.BooleanColumn(
-        verbose_name='Active'
+        verbose_name=_('Active')
     )
     is_synced = columns.BooleanColumn(
         orderable=False,
-        verbose_name='Synced'
+        verbose_name=_('Synced')
     )
 
     class Meta(NetBoxTable.Meta):
@@ -328,17 +388,20 @@ class ConfigContextTable(NetBoxTable):
 
 class ConfigTemplateTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     data_source = tables.Column(
+        verbose_name=_('Data Source'),
         linkify=True
     )
     data_file = tables.Column(
+        verbose_name=_('Data File'),
         linkify=True
     )
     is_synced = columns.BooleanColumn(
         orderable=False,
-        verbose_name='Synced'
+        verbose_name=_('Synced')
     )
     tags = columns.TagColumn(
         url_name='extras:configtemplate_list'
@@ -357,31 +420,34 @@ class ConfigTemplateTable(NetBoxTable):
 
 class ObjectChangeTable(NetBoxTable):
     time = tables.DateTimeColumn(
+        verbose_name=_('Time'),
         linkify=True,
         format=settings.SHORT_DATETIME_FORMAT
     )
     user_name = tables.Column(
-        verbose_name='Username'
+        verbose_name=_('Username')
     )
     full_name = tables.TemplateColumn(
         accessor=tables.A('user'),
         template_code=OBJECTCHANGE_FULL_NAME,
-        verbose_name='Full Name',
+        verbose_name=_('Full Name'),
         orderable=False
     )
-    action = columns.ChoiceFieldColumn()
+    action = columns.ChoiceFieldColumn(
+        verbose_name=_('Action'),
+    )
     changed_object_type = columns.ContentTypeColumn(
-        verbose_name='Type'
+        verbose_name=_('Type')
     )
     object_repr = tables.TemplateColumn(
         accessor=tables.A('changed_object'),
         template_code=OBJECTCHANGE_OBJECT,
-        verbose_name='Object',
+        verbose_name=_('Object'),
         orderable=False
     )
     request_id = tables.TemplateColumn(
         template_code=OBJECTCHANGE_REQUEST_ID,
-        verbose_name='Request ID'
+        verbose_name=_('Request ID')
     )
     actions = columns.ActionsColumn(
         actions=()
@@ -397,23 +463,28 @@ class ObjectChangeTable(NetBoxTable):
 
 class JournalEntryTable(NetBoxTable):
     created = tables.DateTimeColumn(
+        verbose_name=_('Created'),
         linkify=True,
         format=settings.SHORT_DATETIME_FORMAT
     )
     assigned_object_type = columns.ContentTypeColumn(
-        verbose_name='Object type'
+        verbose_name=_('Object Type')
     )
     assigned_object = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Object'
+        verbose_name=_('Object')
+    )
+    kind = columns.ChoiceFieldColumn(
+        verbose_name=_('Kind'),
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    kind = columns.ChoiceFieldColumn()
-    comments = columns.MarkdownColumn()
     comments_short = tables.TemplateColumn(
         accessor=tables.A('comments'),
         template_code='{{ value|markdown|truncatewords_html:50 }}',
-        verbose_name='Comments (Short)'
+        verbose_name=_('Comments (Short)')
     )
     tags = columns.TagColumn(
         url_name='extras:journalentry_list'

+ 8 - 2
netbox/ipam/tables/asn.py

@@ -1,5 +1,5 @@
 import django_tables2 as tables
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
 
 from ipam.models import *
 from netbox.tables import NetBoxTable, columns
@@ -13,9 +13,11 @@ __all__ = (
 
 class ASNRangeTable(TenancyColumnsMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     rir = tables.Column(
+        verbose_name=_('RIR'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -36,9 +38,11 @@ class ASNRangeTable(TenancyColumnsMixin, NetBoxTable):
 
 class ASNTable(TenancyColumnsMixin, NetBoxTable):
     asn = tables.Column(
+        verbose_name=_('ASN'),
         linkify=True
     )
     rir = tables.Column(
+        verbose_name=_('RIR'),
         linkify=True
     )
     asn_asdot = tables.Column(
@@ -60,7 +64,9 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
         linkify_item=True,
         verbose_name=_('Sites')
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:asn_list'
     )

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

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from ipam.models import *
@@ -18,17 +19,20 @@ IPADDRESSES = """
 
 class FHRPGroupTable(NetBoxTable):
     group_id = tables.Column(
+        verbose_name=_('Group ID'),
         linkify=True
     )
     ip_addresses = tables.TemplateColumn(
         template_code=IPADDRESSES,
         orderable=False,
-        verbose_name='IP Addresses'
+        verbose_name=_('IP Addresses')
     )
     member_count = tables.Column(
-        verbose_name='Members'
+        verbose_name=_('Members')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='ipam:fhrpgroup_list'
     )
@@ -52,13 +56,15 @@ class FHRPGroupAssignmentTable(NetBoxTable):
         accessor=tables.A('interface__parent_object'),
         linkify=True,
         orderable=False,
-        verbose_name='Parent'
+        verbose_name=_('Parent')
     )
     interface = tables.Column(
         linkify=True,
-        orderable=False
+        orderable=False,
+        verbose_name=_('Interface'),
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
     actions = columns.ActionsColumn(

+ 67 - 36
netbox/ipam/tables/ip.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django.utils.safestring import mark_safe
 from django_tables2.utils import Accessor
@@ -81,15 +82,16 @@ VRF_LINK = """
 
 class RIRTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     is_private = columns.BooleanColumn(
-        verbose_name='Private'
+        verbose_name=_('Private')
     )
     aggregate_count = columns.LinkedCountColumn(
         viewname='ipam:aggregate_list',
         url_params={'rir_id': 'pk'},
-        verbose_name='Aggregates'
+        verbose_name=_('Aggregates')
     )
     tags = columns.TagColumn(
         url_name='ipam:rir_list'
@@ -111,7 +113,7 @@ class RIRTable(NetBoxTable):
 class AggregateTable(TenancyColumnsMixin, NetBoxTable):
     prefix = tables.Column(
         linkify=True,
-        verbose_name='Aggregate',
+        verbose_name=_('Aggregate'),
         attrs={
             # Allow the aggregate to be copied to the clipboard
             'a': {'id': lambda record: f"aggregate_{record.pk}"}
@@ -119,16 +121,19 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
     )
     date_added = tables.DateColumn(
         format="Y-m-d",
-        verbose_name='Added'
+        verbose_name=_('Added')
     )
     child_count = tables.Column(
-        verbose_name='Prefixes'
+        verbose_name=_('Prefixes')
     )
     utilization = columns.UtilizationColumn(
+        verbose_name=_('Utilization'),
         accessor='get_utilization',
         orderable=False
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:aggregate_list'
     )
@@ -151,22 +156,23 @@ class AggregateTable(TenancyColumnsMixin, NetBoxTable):
 
 class RoleTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     prefix_count = columns.LinkedCountColumn(
         viewname='ipam:prefix_list',
         url_params={'role_id': 'pk'},
-        verbose_name='Prefixes'
+        verbose_name=_('Prefixes')
     )
     iprange_count = columns.LinkedCountColumn(
         viewname='ipam:iprange_list',
         url_params={'role_id': 'pk'},
-        verbose_name='IP Ranges'
+        verbose_name=_('IP Ranges')
     )
     vlan_count = columns.LinkedCountColumn(
         viewname='ipam:vlan_list',
         url_params={'role_id': 'pk'},
-        verbose_name='VLANs'
+        verbose_name=_('VLANs')
     )
     tags = columns.TagColumn(
         url_name='ipam:role_list'
@@ -202,6 +208,7 @@ class PrefixUtilizationColumn(columns.UtilizationColumn):
 
 class PrefixTable(TenancyColumnsMixin, NetBoxTable):
     prefix = columns.TemplateColumn(
+        verbose_name=_('Prefix'),
         template_code=PREFIX_LINK_WITH_DEPTH,
         export_raw=True,
         attrs={'td': {'class': 'text-nowrap'}}
@@ -210,11 +217,11 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
         accessor=Accessor('prefix'),
         template_code=PREFIX_LINK,
         export_raw=True,
-        verbose_name='Prefix (Flat)'
+        verbose_name=_('Prefix (Flat)')
     )
     depth = tables.Column(
         accessor=Accessor('_depth'),
-        verbose_name='Depth'
+        verbose_name=_('Depth')
     )
     children = columns.LinkedCountColumn(
         accessor=Accessor('_children'),
@@ -223,41 +230,47 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
             'vrf_id': 'vrf_id',
             'within': 'prefix',
         },
-        verbose_name='Children'
+        verbose_name=_('Children')
     )
     status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
         default=AVAILABLE_LABEL
     )
     vrf = tables.TemplateColumn(
         template_code=VRF_LINK,
-        verbose_name='VRF'
+        verbose_name=_('VRF')
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     vlan_group = tables.Column(
         accessor='vlan__group',
         linkify=True,
-        verbose_name='VLAN Group'
+        verbose_name=_('VLAN Group')
     )
     vlan = tables.Column(
         linkify=True,
-        verbose_name='VLAN'
+        verbose_name=_('VLAN')
     )
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
     is_pool = columns.BooleanColumn(
-        verbose_name='Pool'
+        verbose_name=_('Pool')
     )
     mark_utilized = columns.BooleanColumn(
-        verbose_name='Marked Utilized'
+        verbose_name=_('Marked Utilized')
     )
     utilization = PrefixUtilizationColumn(
+        verbose_name=_('Utilization'),
         accessor='get_utilization',
         orderable=False
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:prefix_list'
     )
@@ -285,26 +298,32 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
 #
 class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
     start_address = tables.Column(
+        verbose_name=_('Start address'),
         linkify=True
     )
     vrf = tables.TemplateColumn(
         template_code=VRF_LINK,
-        verbose_name='VRF'
+        verbose_name=_('VRF')
     )
     status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
         default=AVAILABLE_LABEL
     )
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
     mark_utilized = columns.BooleanColumn(
-        verbose_name='Marked Utilized'
+        verbose_name=_('Marked Utilized')
     )
     utilization = columns.UtilizationColumn(
+        verbose_name=_('Utilization'),
         accessor='utilization',
         orderable=False
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:iprange_list'
     )
@@ -330,43 +349,48 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
 class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
     address = tables.TemplateColumn(
         template_code=IPADDRESS_LINK,
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
     )
     vrf = tables.TemplateColumn(
         template_code=VRF_LINK,
-        verbose_name='VRF'
+        verbose_name=_('VRF')
     )
     status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
         default=AVAILABLE_LABEL
     )
-    role = columns.ChoiceFieldColumn()
+    role = columns.ChoiceFieldColumn(
+        verbose_name=_('Role'),
+    )
     assigned_object = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Interface'
+        verbose_name=_('Interface')
     )
     assigned_object_parent = tables.Column(
         accessor='assigned_object__parent_object',
         linkify=True,
         orderable=False,
-        verbose_name='Device/VM'
+        verbose_name=_('Parent')
     )
     nat_inside = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='NAT (Inside)'
+        verbose_name=_('NAT (Inside)')
     )
     nat_outside = tables.ManyToManyColumn(
         linkify_item=True,
         orderable=False,
-        verbose_name='NAT (Outside)'
+        verbose_name=_('NAT (Outside)')
     )
     assigned = columns.BooleanColumn(
         accessor='assigned_object_id',
         linkify=lambda record: record.assigned_object.get_absolute_url(),
-        verbose_name='Assigned'
+        verbose_name=_('Assigned')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='ipam:ipaddress_list'
     )
@@ -391,10 +415,13 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
 class IPAddressAssignTable(NetBoxTable):
     address = tables.TemplateColumn(
         template_code=IPADDRESS_ASSIGN_LINK,
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
+    )
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
     )
-    status = columns.ChoiceFieldColumn()
     assigned_object = tables.Column(
+        verbose_name=_('Assigned Object'),
         orderable=False
     )
 
@@ -411,14 +438,18 @@ class AssignedIPAddressesTable(NetBoxTable):
     """
     address = tables.Column(
         linkify=True,
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
     )
     vrf = tables.TemplateColumn(
         template_code=VRF_LINK,
-        verbose_name='VRF'
+        verbose_name=_('VRF')
+    )
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
+    tenant = TenantColumn(
+        verbose_name=_('Tenant'),
     )
-    status = columns.ChoiceFieldColumn()
-    tenant = TenantColumn()
 
     class Meta(NetBoxTable.Meta):
         model = IPAddress

+ 12 - 6
netbox/ipam/tables/l2vpn.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from ipam.models import L2VPN, L2VPNTermination
@@ -19,17 +20,22 @@ L2VPN_TARGETS = """
 class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
     pk = columns.ToggleColumn()
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     import_targets = columns.TemplateColumn(
+        verbose_name=_('Import Targets'),
         template_code=L2VPN_TARGETS,
         orderable=False
     )
     export_targets = columns.TemplateColumn(
+        verbose_name=_('Export Targets'),
         template_code=L2VPN_TARGETS,
         orderable=False
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:l2vpn_list'
     )
@@ -46,26 +52,26 @@ class L2VPNTable(TenancyColumnsMixin, NetBoxTable):
 class L2VPNTerminationTable(NetBoxTable):
     pk = columns.ToggleColumn()
     l2vpn = tables.Column(
-        verbose_name='L2VPN',
+        verbose_name=_('L2VPN'),
         linkify=True
     )
     assigned_object_type = columns.ContentTypeColumn(
-        verbose_name='Object Type'
+        verbose_name=_('Object Type')
     )
     assigned_object = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Object'
+        verbose_name=_('Object')
     )
     assigned_object_parent = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Object Parent'
+        verbose_name=_('Object Parent')
     )
     assigned_object_site = tables.Column(
         linkify=True,
         orderable=False,
-        verbose_name='Object Site'
+        verbose_name=_('Object Site')
     )
 
     class Meta(NetBoxTable.Meta):

+ 12 - 2
netbox/ipam/tables/services.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from ipam.models import *
@@ -11,13 +12,17 @@ __all__ = (
 
 class ServiceTemplateTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     ports = tables.Column(
+        verbose_name=_('Ports'),
         accessor=tables.A('port_list'),
         order_by=tables.A('ports'),
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:servicetemplate_list'
     )
@@ -32,17 +37,22 @@ class ServiceTemplateTable(NetBoxTable):
 
 class ServiceTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     parent = tables.Column(
+        verbose_name=_('Parent'),
         linkify=True,
         order_by=('device', 'virtual_machine')
     )
     ports = tables.Column(
+        verbose_name=_('Ports'),
         accessor=tables.A('port_list'),
         order_by=tables.A('ports'),
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:service_list'
     )

+ 39 - 14
netbox/ipam/tables/vlans.py

@@ -1,5 +1,6 @@
 import django_tables2 as tables
 from django.utils.safestring import mark_safe
+from django.utils.translation import gettext_lazy as _
 from django_tables2.utils import Accessor
 
 from dcim.models import Interface
@@ -59,20 +60,26 @@ VLAN_MEMBER_TAGGED = """
 #
 
 class VLANGroupTable(NetBoxTable):
-    name = tables.Column(linkify=True)
-    scope_type = columns.ContentTypeColumn()
+    name = tables.Column(
+        verbose_name=_('Name'),
+        linkify=True
+    )
+    scope_type = columns.ContentTypeColumn(
+        verbose_name=_('Scope Type'),
+    )
     scope = tables.Column(
+        verbose_name=_('Scope'),
         linkify=True,
         orderable=False
     )
     vlan_count = columns.LinkedCountColumn(
         viewname='ipam:vlan_list',
         url_params={'group_id': 'pk'},
-        verbose_name='VLANs'
+        verbose_name=_('VLANs')
     )
     utilization = columns.UtilizationColumn(
         orderable=False,
-        verbose_name='Utilization'
+        verbose_name=_('Utilization')
     )
     tags = columns.TagColumn(
         url_name='ipam:vlangroup_list'
@@ -97,35 +104,42 @@ class VLANGroupTable(NetBoxTable):
 class VLANTable(TenancyColumnsMixin, NetBoxTable):
     vid = tables.TemplateColumn(
         template_code=VLAN_LINK,
-        verbose_name='VID'
+        verbose_name=_('VID')
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
     status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
         default=AVAILABLE_LABEL
     )
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
     l2vpn = tables.Column(
         accessor=tables.A('l2vpn_termination__l2vpn'),
         linkify=True,
         orderable=False,
-        verbose_name='L2VPN'
+        verbose_name=_('L2VPN')
     )
     prefixes = columns.TemplateColumn(
         template_code=VLAN_PREFIXES,
         orderable=False,
-        verbose_name='Prefixes'
+        verbose_name=_('Prefixes')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='ipam:vlan_list'
     )
@@ -148,9 +162,10 @@ class VLANMembersTable(NetBoxTable):
     """
     name = tables.Column(
         linkify=True,
-        verbose_name='Interface'
+        verbose_name=_('Interface')
     )
     tagged = tables.TemplateColumn(
+        verbose_name=_('Tagged'),
         template_code=VLAN_MEMBER_TAGGED,
         orderable=False
     )
@@ -158,6 +173,7 @@ class VLANMembersTable(NetBoxTable):
 
 class VLANDevicesTable(VLANMembersTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     actions = columns.ActionsColumn(
@@ -172,6 +188,7 @@ class VLANDevicesTable(VLANMembersTable):
 
 class VLANVirtualMachinesTable(VLANMembersTable):
     virtual_machine = tables.Column(
+        verbose_name=_('Virtual Machine'),
         linkify=True
     )
     actions = columns.ActionsColumn(
@@ -190,19 +207,27 @@ class InterfaceVLANTable(NetBoxTable):
     """
     vid = tables.Column(
         linkify=True,
-        verbose_name='ID'
+        verbose_name=_('VID')
+    )
+    tagged = columns.BooleanColumn(
+        verbose_name=_('Tagged'),
     )
-    tagged = columns.BooleanColumn()
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     group = tables.Column(
         accessor=Accessor('group__name'),
-        verbose_name='Group'
+        verbose_name=_('Group')
+    )
+    tenant = TenantColumn(
+        verbose_name=_('Tenant'),
+    )
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
     )
-    tenant = TenantColumn()
-    status = columns.ChoiceFieldColumn()
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
 

+ 13 - 4
netbox/ipam/tables/vrfs.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from ipam.models import *
@@ -22,23 +23,28 @@ VRF_TARGETS = """
 
 class VRFTable(TenancyColumnsMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     rd = tables.Column(
-        verbose_name='RD'
+        verbose_name=_('RD')
     )
     enforce_unique = columns.BooleanColumn(
-        verbose_name='Unique'
+        verbose_name=_('Unique')
     )
     import_targets = columns.TemplateColumn(
+        verbose_name=_('Import Targets'),
         template_code=VRF_TARGETS,
         orderable=False
     )
     export_targets = columns.TemplateColumn(
+        verbose_name=_('Export Targets'),
         template_code=VRF_TARGETS,
         orderable=False
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:vrf_list'
     )
@@ -58,9 +64,12 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
 
 class RouteTargetTable(TenancyColumnsMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='ipam:routetarget_list'
     )

+ 13 - 7
netbox/netbox/tables/columns.py

@@ -12,6 +12,7 @@ from django.utils.dateparse import parse_date
 from django.utils.formats import date_format
 from django.utils.html import escape
 from django.utils.safestring import mark_safe
+from django.utils.translation import gettext_lazy as _
 from django_tables2.columns import library
 from django_tables2.utils import Accessor
 
@@ -170,7 +171,8 @@ class ToggleColumn(tables.CheckBoxColumn):
 
     @property
     def header(self):
-        return mark_safe('<input type="checkbox" class="toggle form-check-input" title="Toggle All" />')
+        title_text = _('Toggle all')
+        return mark_safe(f'<input type="checkbox" class="toggle form-check-input" title="{title_text}" />')
 
 
 class BooleanColumn(tables.Column):
@@ -271,12 +273,13 @@ class ActionsColumn(tables.Column):
                     )
 
         # Create the actions dropdown menu
+        toggle_text = _('Toggle Dropdown')
         if button and dropdown_links:
             html += (
                 f'<span class="btn-group dropdown">'
                 f'  {button}'
                 f'  <a class="btn btn-sm btn-{dropdown_class} dropdown-toggle" type="button" data-bs-toggle="dropdown" style="padding-left: 2px">'
-                f'  <span class="visually-hidden">Toggle Dropdown</span></a>'
+                f'  <span class="visually-hidden">{toggle_text}</span></a>'
                 f'  <ul class="dropdown-menu">{"".join(dropdown_links)}</ul>'
                 f'</span>'
             )
@@ -286,7 +289,7 @@ class ActionsColumn(tables.Column):
             html += (
                 f'<span class="btn-group dropdown">'
                 f'  <a class="btn btn-sm btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">'
-                f'  <span class="visually-hidden">Toggle Dropdown</span></a>'
+                f'  <span class="visually-hidden">{toggle_text}</span></a>'
                 f'  <ul class="dropdown-menu">{"".join(dropdown_links)}</ul>'
                 f'</span>'
             )
@@ -440,7 +443,8 @@ class TagColumn(tables.TemplateColumn):
         super().__init__(
             orderable=False,
             template_code=self.template_code,
-            extra_context={'url_name': url_name}
+            extra_context={'url_name': url_name},
+            verbose_name=_('Tags'),
         )
 
     def value(self, value):
@@ -522,7 +526,8 @@ class CustomLinkColumn(tables.Column):
             if rendered:
                 return mark_safe(f'<a href="{rendered["link"]}"{rendered["link_target"]}>{rendered["text"]}</a>')
         except Exception as e:
-            return mark_safe(f'<span class="text-danger" title="{e}"><i class="mdi mdi-alert"></i> Error</span>')
+            error_text = _('Error')
+            return mark_safe(f'<span class="text-danger" title="{e}"><i class="mdi mdi-alert"></i> {error_text}</span>')
         return ''
 
     def value(self, record):
@@ -587,9 +592,10 @@ class MarkdownColumn(tables.TemplateColumn):
     {% endif %}
     """
 
-    def __init__(self):
+    def __init__(self, **kwargs):
         super().__init__(
-            template_code=self.template_code
+            template_code=self.template_code,
+            **kwargs,
         )
 
     def value(self, value):

+ 9 - 4
netbox/netbox/tables/tables.py

@@ -7,7 +7,7 @@ from django.db.models.fields.related import RelatedField
 from django.urls import reverse
 from django.urls.exceptions import NoReverseMatch
 from django.utils.safestring import mark_safe
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
 from django_tables2.data import TableQuerysetData
 
 from extras.models import CustomField, CustomLink
@@ -174,7 +174,7 @@ class NetBoxTable(BaseTable):
     )
     id = tables.Column(
         linkify=True,
-        verbose_name='ID'
+        verbose_name=_('ID')
     )
     actions = columns.ActionsColumn()
 
@@ -223,11 +223,16 @@ class SearchTable(tables.Table):
         order_by="object___meta__verbose_name",
     )
     object = tables.Column(
+        verbose_name=_('Object'),
         linkify=True,
         order_by=('name', )
     )
-    field = tables.Column()
-    value = tables.Column()
+    field = tables.Column(
+        verbose_name=_('Field'),
+    )
+    value = tables.Column(
+        verbose_name=_('Value'),
+    )
 
     trim_length = 30
 

+ 9 - 3
netbox/tenancy/tables/columns.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from netbox.tables import columns
@@ -47,7 +48,7 @@ class TenantGroupColumn(tables.TemplateColumn):
 
     def __init__(self, accessor=tables.A('tenant__group'), *args, **kwargs):
         if 'verbose_name' not in kwargs:
-            kwargs['verbose_name'] = 'Tenant Group'
+            kwargs['verbose_name'] = _('Tenant Group')
 
         super().__init__(template_code=self.template_code, accessor=accessor, *args, **kwargs)
 
@@ -56,12 +57,17 @@ class TenantGroupColumn(tables.TemplateColumn):
 
 
 class TenancyColumnsMixin(tables.Table):
-    tenant_group = TenantGroupColumn()
-    tenant = TenantColumn()
+    tenant_group = TenantGroupColumn(
+        verbose_name=_('Tenant Group'),
+    )
+    tenant = TenantColumn(
+        verbose_name=_('Tenant'),
+    )
 
 
 class ContactsColumnMixin(tables.Table):
     contacts = columns.ManyToManyColumn(
+        verbose_name=_('Contacts'),
         linkify_item=True,
         transform=lambda obj: obj.contact.name
     )

+ 21 - 10
netbox/tenancy/tables/contacts.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from django_tables2.utils import Accessor
 
@@ -15,12 +16,13 @@ __all__ = (
 
 class ContactGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     contact_count = columns.LinkedCountColumn(
         viewname='tenancy:contact_list',
         url_params={'group_id': 'pk'},
-        verbose_name='Contacts'
+        verbose_name=_('Contacts')
     )
     tags = columns.TagColumn(
         url_name='tenancy:contactgroup_list'
@@ -36,6 +38,7 @@ class ContactGroupTable(NetBoxTable):
 
 class ContactRoleTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -50,19 +53,24 @@ class ContactRoleTable(NetBoxTable):
 
 class ContactTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
     phone = tables.Column(
+        verbose_name=_('Phone'),
         linkify=linkify_phone,
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     assignment_count = columns.LinkedCountColumn(
         viewname='tenancy:contactassignment_list',
         url_params={'contact_id': 'pk'},
-        verbose_name='Assignments'
+        verbose_name=_('Assignments')
     )
     tags = columns.TagColumn(
         url_name='tenancy:contact_list'
@@ -79,41 +87,44 @@ class ContactTable(NetBoxTable):
 
 class ContactAssignmentTable(NetBoxTable):
     content_type = columns.ContentTypeColumn(
-        verbose_name='Object Type'
+        verbose_name=_('Object Type')
     )
     object = tables.Column(
+        verbose_name=_('Object'),
         linkify=True,
         orderable=False
     )
     contact = tables.Column(
+        verbose_name=_('Contact'),
         linkify=True
     )
     role = tables.Column(
+        verbose_name=_('Role'),
         linkify=True
     )
     contact_title = tables.Column(
         accessor=Accessor('contact__title'),
-        verbose_name='Contact Title'
+        verbose_name=_('Contact Title')
     )
     contact_phone = tables.Column(
         accessor=Accessor('contact__phone'),
-        verbose_name='Contact Phone'
+        verbose_name=_('Contact Phone')
     )
     contact_email = tables.Column(
         accessor=Accessor('contact__email'),
-        verbose_name='Contact Email'
+        verbose_name=_('Contact Email')
     )
     contact_address = tables.Column(
         accessor=Accessor('contact__address'),
-        verbose_name='Contact Address'
+        verbose_name=_('Contact Address')
     )
     contact_link = tables.Column(
         accessor=Accessor('contact__link'),
-        verbose_name='Contact Link'
+        verbose_name=_('Contact Link')
     )
     contact_description = tables.Column(
         accessor=Accessor('contact__description'),
-        verbose_name='Contact Description'
+        verbose_name=_('Contact Description')
     )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete')

+ 8 - 2
netbox/tenancy/tables/tenants.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from tenancy.models import *
 from tenancy.tables import ContactsColumnMixin
@@ -12,12 +13,13 @@ __all__ = (
 
 class TenantGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     tenant_count = columns.LinkedCountColumn(
         viewname='tenancy:tenant_list',
         url_params={'group_id': 'pk'},
-        verbose_name='Tenants'
+        verbose_name=_('Tenants')
     )
     tags = columns.TagColumn(
         url_name='tenancy:tenantgroup_list'
@@ -33,12 +35,16 @@ class TenantGroupTable(NetBoxTable):
 
 class TenantTable(ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
-    comments = columns.MarkdownColumn()
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
         url_name='tenancy:tenant_list'
     )

+ 40 - 11
netbox/users/tables.py

@@ -28,14 +28,22 @@ class TokenTable(UserTokenTable):
 
 class UserTable(NetBoxTable):
     username = tables.Column(
+        verbose_name=_('Username'),
         linkify=True
     )
     groups = columns.ManyToManyColumn(
+        verbose_name=_('Groups'),
         linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
     )
-    is_active = columns.BooleanColumn()
-    is_staff = columns.BooleanColumn()
-    is_superuser = columns.BooleanColumn()
+    is_active = columns.BooleanColumn(
+        verbose_name=_('Is Active'),
+    )
+    is_staff = columns.BooleanColumn(
+        verbose_name=_('Is Staff'),
+    )
+    is_superuser = columns.BooleanColumn(
+        verbose_name=_('Is Superuser'),
+    )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
     )
@@ -50,7 +58,10 @@ class UserTable(NetBoxTable):
 
 
 class GroupTable(NetBoxTable):
-    name = tables.Column(linkify=True)
+    name = tables.Column(
+        verbose_name=_('Name'),
+        linkify=True
+    )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
     )
@@ -64,20 +75,38 @@ class GroupTable(NetBoxTable):
 
 
 class ObjectPermissionTable(NetBoxTable):
-    name = tables.Column(linkify=True)
-    object_types = columns.ContentTypesColumn()
-    enabled = columns.BooleanColumn()
-    can_view = columns.BooleanColumn()
-    can_add = columns.BooleanColumn()
-    can_change = columns.BooleanColumn()
-    can_delete = columns.BooleanColumn()
+    name = tables.Column(
+        verbose_name=_('Name'),
+        linkify=True
+    )
+    object_types = columns.ContentTypesColumn(
+        verbose_name=_('Object Types'),
+    )
+    enabled = columns.BooleanColumn(
+        verbose_name=_('Enabled'),
+    )
+    can_view = columns.BooleanColumn(
+        verbose_name=_('Can View'),
+    )
+    can_add = columns.BooleanColumn(
+        verbose_name=_('Can Add'),
+    )
+    can_change = columns.BooleanColumn(
+        verbose_name=_('Can Change'),
+    )
+    can_delete = columns.BooleanColumn(
+        verbose_name=_('Can Delete'),
+    )
     custom_actions = columns.ArrayColumn(
+        verbose_name=_('Custom Actions'),
         accessor=tables.A('actions')
     )
     users = columns.ManyToManyColumn(
+        verbose_name=_('Users'),
         linkify_item=('users:netboxuser', {'pk': tables.A('pk')})
     )
     groups = columns.ManyToManyColumn(
+        verbose_name=_('Groups'),
         linkify_item=('users:netboxgroup', {'pk': tables.A('pk')})
     )
     actions = columns.ActionsColumn(

+ 17 - 6
netbox/virtualization/tables/clusters.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
 from virtualization.models import Cluster, ClusterGroup, ClusterType
@@ -13,12 +14,13 @@ __all__ = (
 
 class ClusterTypeTable(NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     cluster_count = columns.LinkedCountColumn(
         viewname='virtualization:cluster_list',
         url_params={'type_id': 'pk'},
-        verbose_name='Clusters'
+        verbose_name=_('Clusters')
     )
     tags = columns.TagColumn(
         url_name='virtualization:clustertype_list'
@@ -34,12 +36,13 @@ class ClusterTypeTable(NetBoxTable):
 
 class ClusterGroupTable(ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     cluster_count = columns.LinkedCountColumn(
         viewname='virtualization:cluster_list',
         url_params={'group_id': 'pk'},
-        verbose_name='Clusters'
+        verbose_name=_('Clusters')
     )
     tags = columns.TagColumn(
         url_name='virtualization:clustergroup_list'
@@ -56,29 +59,37 @@ class ClusterGroupTable(ContactsColumnMixin, NetBoxTable):
 
 class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     type = tables.Column(
+        verbose_name=_('Type'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     device_count = columns.LinkedCountColumn(
         viewname='dcim:device_list',
         url_params={'cluster_id': 'pk'},
-        verbose_name='Devices'
+        verbose_name=_('Devices')
     )
     vm_count = columns.LinkedCountColumn(
         viewname='virtualization:virtualmachine_list',
         url_params={'cluster_id': 'pk'},
-        verbose_name='VMs'
+        verbose_name=_('VMs')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='virtualization:cluster_list'
     )

+ 22 - 7
netbox/virtualization/tables/virtualmachines.py

@@ -1,5 +1,5 @@
 import django_tables2 as tables
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
 
 from dcim.tables.devices import BaseInterfaceTable
 from netbox.tables import NetBoxTable, columns
@@ -40,33 +40,43 @@ VMINTERFACE_BUTTONS = """
 
 class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
     name = tables.Column(
+        verbose_name=_('Name'),
         order_by=('_name',),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     site = tables.Column(
+        verbose_name=_('Site'),
         linkify=True
     )
     cluster = tables.Column(
+        verbose_name=_('Cluster'),
         linkify=True
     )
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
-    role = columns.ColoredLabelColumn()
-    comments = columns.MarkdownColumn()
+    role = columns.ColoredLabelColumn(
+        verbose_name=_('Role'),
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     primary_ip4 = tables.Column(
         linkify=True,
-        verbose_name='IPv4 Address'
+        verbose_name=_('IPv4 Address')
     )
     primary_ip6 = tables.Column(
         linkify=True,
-        verbose_name='IPv6 Address'
+        verbose_name=_('IPv6 Address')
     )
     primary_ip = tables.Column(
         linkify=True,
         order_by=('primary_ip4', 'primary_ip6'),
-        verbose_name='IP Address'
+        verbose_name=_('IP Address')
     )
     tags = columns.TagColumn(
         url_name='virtualization:virtualmachine_list'
@@ -93,12 +103,15 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable)
 
 class VMInterfaceTable(BaseInterfaceTable):
     virtual_machine = tables.Column(
+        verbose_name=_('Virtual Machine'),
         linkify=True
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
     vrf = tables.Column(
+        verbose_name=_('VRF'),
         linkify=True
     )
     tags = columns.TagColumn(
@@ -116,9 +129,11 @@ class VMInterfaceTable(BaseInterfaceTable):
 
 class VirtualMachineVMInterfaceTable(VMInterfaceTable):
     parent = tables.Column(
+        verbose_name=_('Parent'),
         linkify=True
     )
     bridge = tables.Column(
+        verbose_name=_('Bridge'),
         linkify=True
     )
     actions = columns.ActionsColumn(

+ 17 - 5
netbox/wireless/tables/wirelesslan.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from dcim.models import Interface
@@ -14,14 +15,17 @@ __all__ = (
 
 class WirelessLANGroupTable(NetBoxTable):
     name = columns.MPTTColumn(
+        verbose_name=_('Name'),
         linkify=True
     )
     wirelesslan_count = columns.LinkedCountColumn(
         viewname='wireless:wirelesslan_list',
         url_params={'group_id': 'pk'},
-        verbose_name='Wireless LANs'
+        verbose_name=_('Wireless LANs')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='wireless:wirelesslangroup_list'
     )
@@ -37,16 +41,22 @@ class WirelessLANGroupTable(NetBoxTable):
 
 class WirelessLANTable(TenancyColumnsMixin, NetBoxTable):
     ssid = tables.Column(
+        verbose_name=_('SSID'),
         linkify=True
     )
     group = tables.Column(
+        verbose_name=_('Group'),
         linkify=True
     )
-    status = columns.ChoiceFieldColumn()
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
+    )
     interface_count = tables.Column(
-        verbose_name='Interfaces'
+        verbose_name=_('Interfaces')
+    )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
     )
-    comments = columns.MarkdownColumn()
     tags = columns.TagColumn(
         url_name='wireless:wirelesslan_list'
     )
@@ -62,9 +72,11 @@ class WirelessLANTable(TenancyColumnsMixin, NetBoxTable):
 
 class WirelessLANInterfacesTable(NetBoxTable):
     device = tables.Column(
+        verbose_name=_('Device'),
         linkify=True
     )
     name = tables.Column(
+        verbose_name=_('Name'),
         linkify=True
     )
 

+ 9 - 2
netbox/wireless/tables/wirelesslink.py

@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
 import django_tables2 as tables
 
 from netbox.tables import NetBoxTable, columns
@@ -12,21 +13,27 @@ __all__ = (
 class WirelessLinkTable(TenancyColumnsMixin, NetBoxTable):
     id = tables.Column(
         linkify=True,
-        verbose_name='ID'
+        verbose_name=_('ID')
+    )
+    status = columns.ChoiceFieldColumn(
+        verbose_name=_('Status'),
     )
-    status = columns.ChoiceFieldColumn()
     device_a = tables.Column(
+        verbose_name=_('Device A'),
         accessor=tables.A('interface_a__device'),
         linkify=True
     )
     interface_a = tables.Column(
+        verbose_name=_('Interface A'),
         linkify=True
     )
     device_b = tables.Column(
+        verbose_name=_('Device B'),
         accessor=tables.A('interface_b__device'),
         linkify=True
     )
     interface_b = tables.Column(
+        verbose_name=_('Interface B'),
         linkify=True
     )
     tags = columns.TagColumn(