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)