diff --git a/netbox/core/tables/config.py b/netbox/core/tables/config.py index 9d4cb6393..018d89edf 100644 --- a/netbox/core/tables/config.py +++ b/netbox/core/tables/config.py @@ -19,6 +19,7 @@ REVISION_BUTTONS = """ class ConfigRevisionTable(NetBoxTable): is_active = columns.BooleanColumn( verbose_name=_('Is Active'), + false_mark=None ) actions = columns.ActionsColumn( actions=('delete',), diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 7fa307bc8..d6435ed4b 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -63,7 +63,10 @@ class DeviceRoleTable(NetBoxTable): verbose_name=_('VMs') ) color = columns.ColorColumn() - vm_role = columns.BooleanColumn() + vm_role = columns.BooleanColumn( + verbose_name=_('VM role'), + false_mark=None + ) config_template = tables.Column( linkify=True ) @@ -329,6 +332,7 @@ class CableTerminationTable(NetBoxTable): ) mark_connected = columns.BooleanColumn( verbose_name=_('Mark Connected'), + false_mark=None ) class Meta: @@ -586,7 +590,8 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi } ) mgmt_only = columns.BooleanColumn( - verbose_name=_('Management Only') + verbose_name=_('Management Only'), + false_mark=None ) speed_formatted = columns.TemplateColumn( template_code='{% load helpers %}{{ value|humanize_speed }}', @@ -913,6 +918,7 @@ class InventoryItemTable(DeviceComponentTable): ) discovered = columns.BooleanColumn( verbose_name=_('Discovered'), + false_mark=None ) parent = tables.Column( linkify=True, diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py index fad238c6e..69ff8b3a2 100644 --- a/netbox/dcim/tables/devicetypes.py +++ b/netbox/dcim/tables/devicetypes.py @@ -86,7 +86,8 @@ class DeviceTypeTable(NetBoxTable): linkify=True ) is_full_depth = columns.BooleanColumn( - verbose_name=_('Full Depth') + verbose_name=_('Full Depth'), + false_mark=None ) comments = columns.MarkdownColumn( verbose_name=_('Comments'), @@ -98,7 +99,10 @@ class DeviceTypeTable(NetBoxTable): verbose_name=_('U Height'), template_code='{{ value|floatformat }}' ) - exclude_from_utilization = columns.BooleanColumn() + exclude_from_utilization = columns.BooleanColumn( + verbose_name=_('Exclude from utilization'), + false_mark=None + ) weight = columns.TemplateColumn( verbose_name=_('Weight'), template_code=WEIGHT, @@ -221,7 +225,8 @@ class InterfaceTemplateTable(ComponentTemplateTable): verbose_name=_('Enabled'), ) mgmt_only = columns.BooleanColumn( - verbose_name=_('Management Only') + verbose_name=_('Management Only'), + false_mark=None ) actions = columns.ActionsColumn( actions=('edit', 'delete'), diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index a120f7f53..420a58638 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -47,7 +47,8 @@ class CustomFieldTable(NetBoxTable): verbose_name=_('Object Types') ) required = columns.BooleanColumn( - verbose_name=_('Required') + verbose_name=_('Required'), + false_mark=None ) ui_visible = columns.ChoiceFieldColumn( verbose_name=_('Visible') @@ -72,6 +73,7 @@ class CustomFieldTable(NetBoxTable): ) is_cloneable = columns.BooleanColumn( verbose_name=_('Is Cloneable'), + false_mark=None ) class Meta(NetBoxTable.Meta): @@ -105,6 +107,7 @@ class CustomFieldChoiceSetTable(NetBoxTable): ) order_alphabetically = columns.BooleanColumn( verbose_name=_('Order Alphabetically'), + false_mark=None ) class Meta(NetBoxTable.Meta): @@ -129,6 +132,7 @@ class CustomLinkTable(NetBoxTable): ) new_window = columns.BooleanColumn( verbose_name=_('New Window'), + false_mark=None ) class Meta(NetBoxTable.Meta): @@ -150,6 +154,7 @@ class ExportTemplateTable(NetBoxTable): ) as_attachment = columns.BooleanColumn( verbose_name=_('As Attachment'), + false_mark=None ) data_source = tables.Column( verbose_name=_('Data Source'), @@ -218,6 +223,7 @@ class SavedFilterTable(NetBoxTable): ) shared = columns.BooleanColumn( verbose_name=_('Shared'), + false_mark=None ) def value_parameters(self, value): diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py index 10dea3a92..4152efefb 100644 --- a/netbox/ipam/tables/ip.py +++ b/netbox/ipam/tables/ip.py @@ -86,7 +86,8 @@ class RIRTable(NetBoxTable): linkify=True ) is_private = columns.BooleanColumn( - verbose_name=_('Private') + verbose_name=_('Private'), + false_mark=None ) aggregate_count = columns.LinkedCountColumn( viewname='ipam:aggregate_list', @@ -258,10 +259,12 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable): linkify=True ) is_pool = columns.BooleanColumn( - verbose_name=_('Pool') + verbose_name=_('Pool'), + false_mark=None ) mark_utilized = columns.BooleanColumn( - verbose_name=_('Marked Utilized') + verbose_name=_('Marked Utilized'), + false_mark=None ) utilization = PrefixUtilizationColumn( verbose_name=_('Utilization'), @@ -314,7 +317,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable): linkify=True ) mark_utilized = columns.BooleanColumn( - verbose_name=_('Marked Utilized') + verbose_name=_('Marked Utilized'), + false_mark=None ) utilization = columns.UtilizationColumn( verbose_name=_('Utilization'), @@ -386,7 +390,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable): assigned = columns.BooleanColumn( accessor='assigned_object_id', linkify=lambda record: record.assigned_object.get_absolute_url(), - verbose_name=_('Assigned') + verbose_name=_('Assigned'), + false_mark=None ) comments = columns.MarkdownColumn( verbose_name=_('Comments'), diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index 11de0381c..4cc13e367 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -211,6 +211,7 @@ class InterfaceVLANTable(NetBoxTable): ) tagged = columns.BooleanColumn( verbose_name=_('Tagged'), + false_mark=None ) site = tables.Column( verbose_name=_('Site'), diff --git a/netbox/ipam/tables/vrfs.py b/netbox/ipam/tables/vrfs.py index 174b99189..5fd9cbfb6 100644 --- a/netbox/ipam/tables/vrfs.py +++ b/netbox/ipam/tables/vrfs.py @@ -30,7 +30,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable): verbose_name=_('RD') ) enforce_unique = columns.BooleanColumn( - verbose_name=_('Unique') + verbose_name=_('Unique'), + false_mark=None ) import_targets = columns.TemplateColumn( verbose_name=_('Import Targets'), diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 499136033..32eaf3515 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -194,14 +194,23 @@ class BooleanColumn(tables.Column): Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode character. """ + TRUE_MARK = mark_safe('') + FALSE_MARK = mark_safe('') + EMPTY_MARK = mark_safe('') # Placeholder + + def __init__(self, *args, true_mark=TRUE_MARK, false_mark=FALSE_MARK, **kwargs): + self.true_mark = true_mark + self.false_mark = false_mark + super().__init__(*args, **kwargs) + def render(self, value): - if value: - rendered = '' - elif value is None: - rendered = '' - else: - rendered = '' - return mark_safe(rendered) + if value is None: + return self.EMPTY_MARK + if value and self.true_mark: + return self.true_mark + if not value and self.false_mark: + return self.false_mark + return self.EMPTY_MARK def value(self, value): return str(value)