Skip to content

Commit 424dda5

Browse files
committed
Closes #16933: Enable toggling true/false marks on BooleanColumn
1 parent 3028f26 commit 424dda5

File tree

8 files changed

+53
-19
lines changed

8 files changed

+53
-19
lines changed

netbox/core/tables/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
class ConfigRevisionTable(NetBoxTable):
2020
is_active = columns.BooleanColumn(
2121
verbose_name=_('Is Active'),
22+
false_mark=None
2223
)
2324
actions = columns.ActionsColumn(
2425
actions=('delete',),

netbox/dcim/tables/devices.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ class DeviceRoleTable(NetBoxTable):
6363
verbose_name=_('VMs')
6464
)
6565
color = columns.ColorColumn()
66-
vm_role = columns.BooleanColumn()
66+
vm_role = columns.BooleanColumn(
67+
verbose_name=_('VM role'),
68+
false_mark=None
69+
)
6770
config_template = tables.Column(
6871
linkify=True
6972
)
@@ -329,6 +332,7 @@ class CableTerminationTable(NetBoxTable):
329332
)
330333
mark_connected = columns.BooleanColumn(
331334
verbose_name=_('Mark Connected'),
335+
false_mark=None
332336
)
333337

334338
class Meta:
@@ -586,7 +590,8 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
586590
}
587591
)
588592
mgmt_only = columns.BooleanColumn(
589-
verbose_name=_('Management Only')
593+
verbose_name=_('Management Only'),
594+
false_mark=None
590595
)
591596
speed_formatted = columns.TemplateColumn(
592597
template_code='{% load helpers %}{{ value|humanize_speed }}',
@@ -913,6 +918,7 @@ class InventoryItemTable(DeviceComponentTable):
913918
)
914919
discovered = columns.BooleanColumn(
915920
verbose_name=_('Discovered'),
921+
false_mark=None
916922
)
917923
parent = tables.Column(
918924
linkify=True,

netbox/dcim/tables/devicetypes.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ class DeviceTypeTable(NetBoxTable):
8686
linkify=True
8787
)
8888
is_full_depth = columns.BooleanColumn(
89-
verbose_name=_('Full Depth')
89+
verbose_name=_('Full Depth'),
90+
false_mark=None
9091
)
9192
comments = columns.MarkdownColumn(
9293
verbose_name=_('Comments'),
@@ -98,7 +99,10 @@ class DeviceTypeTable(NetBoxTable):
9899
verbose_name=_('U Height'),
99100
template_code='{{ value|floatformat }}'
100101
)
101-
exclude_from_utilization = columns.BooleanColumn()
102+
exclude_from_utilization = columns.BooleanColumn(
103+
verbose_name=_('Exclude from utilization'),
104+
false_mark=None
105+
)
102106
weight = columns.TemplateColumn(
103107
verbose_name=_('Weight'),
104108
template_code=WEIGHT,
@@ -221,7 +225,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
221225
verbose_name=_('Enabled'),
222226
)
223227
mgmt_only = columns.BooleanColumn(
224-
verbose_name=_('Management Only')
228+
verbose_name=_('Management Only'),
229+
false_mark=None
225230
)
226231
actions = columns.ActionsColumn(
227232
actions=('edit', 'delete'),

netbox/extras/tables/tables.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class CustomFieldTable(NetBoxTable):
4747
verbose_name=_('Object Types')
4848
)
4949
required = columns.BooleanColumn(
50-
verbose_name=_('Required')
50+
verbose_name=_('Required'),
51+
false_mark=None
5152
)
5253
ui_visible = columns.ChoiceFieldColumn(
5354
verbose_name=_('Visible')
@@ -72,6 +73,7 @@ class CustomFieldTable(NetBoxTable):
7273
)
7374
is_cloneable = columns.BooleanColumn(
7475
verbose_name=_('Is Cloneable'),
76+
false_mark=None
7577
)
7678

7779
class Meta(NetBoxTable.Meta):
@@ -105,6 +107,7 @@ class CustomFieldChoiceSetTable(NetBoxTable):
105107
)
106108
order_alphabetically = columns.BooleanColumn(
107109
verbose_name=_('Order Alphabetically'),
110+
false_mark=None
108111
)
109112

110113
class Meta(NetBoxTable.Meta):
@@ -129,6 +132,7 @@ class CustomLinkTable(NetBoxTable):
129132
)
130133
new_window = columns.BooleanColumn(
131134
verbose_name=_('New Window'),
135+
false_mark=None
132136
)
133137

134138
class Meta(NetBoxTable.Meta):
@@ -150,6 +154,7 @@ class ExportTemplateTable(NetBoxTable):
150154
)
151155
as_attachment = columns.BooleanColumn(
152156
verbose_name=_('As Attachment'),
157+
false_mark=None
153158
)
154159
data_source = tables.Column(
155160
verbose_name=_('Data Source'),
@@ -218,6 +223,7 @@ class SavedFilterTable(NetBoxTable):
218223
)
219224
shared = columns.BooleanColumn(
220225
verbose_name=_('Shared'),
226+
false_mark=None
221227
)
222228

223229
def value_parameters(self, value):

netbox/ipam/tables/ip.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ class RIRTable(NetBoxTable):
8686
linkify=True
8787
)
8888
is_private = columns.BooleanColumn(
89-
verbose_name=_('Private')
89+
verbose_name=_('Private'),
90+
false_mark=None
9091
)
9192
aggregate_count = columns.LinkedCountColumn(
9293
viewname='ipam:aggregate_list',
@@ -258,10 +259,12 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
258259
linkify=True
259260
)
260261
is_pool = columns.BooleanColumn(
261-
verbose_name=_('Pool')
262+
verbose_name=_('Pool'),
263+
false_mark=None
262264
)
263265
mark_utilized = columns.BooleanColumn(
264-
verbose_name=_('Marked Utilized')
266+
verbose_name=_('Marked Utilized'),
267+
false_mark=None
265268
)
266269
utilization = PrefixUtilizationColumn(
267270
verbose_name=_('Utilization'),
@@ -314,7 +317,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
314317
linkify=True
315318
)
316319
mark_utilized = columns.BooleanColumn(
317-
verbose_name=_('Marked Utilized')
320+
verbose_name=_('Marked Utilized'),
321+
false_mark=None
318322
)
319323
utilization = columns.UtilizationColumn(
320324
verbose_name=_('Utilization'),
@@ -386,7 +390,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
386390
assigned = columns.BooleanColumn(
387391
accessor='assigned_object_id',
388392
linkify=lambda record: record.assigned_object.get_absolute_url(),
389-
verbose_name=_('Assigned')
393+
verbose_name=_('Assigned'),
394+
false_mark=None
390395
)
391396
comments = columns.MarkdownColumn(
392397
verbose_name=_('Comments'),

netbox/ipam/tables/vlans.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class InterfaceVLANTable(NetBoxTable):
211211
)
212212
tagged = columns.BooleanColumn(
213213
verbose_name=_('Tagged'),
214+
false_mark=None
214215
)
215216
site = tables.Column(
216217
verbose_name=_('Site'),

netbox/ipam/tables/vrfs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
3030
verbose_name=_('RD')
3131
)
3232
enforce_unique = columns.BooleanColumn(
33-
verbose_name=_('Unique')
33+
verbose_name=_('Unique'),
34+
false_mark=None
3435
)
3536
import_targets = columns.TemplateColumn(
3637
verbose_name=_('Import Targets'),

netbox/netbox/tables/columns.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,23 @@ class BooleanColumn(tables.Column):
194194
Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode
195195
character.
196196
"""
197+
TRUE_MARK = mark_safe('<span class="text-success"><i class="mdi mdi-check-bold"></i></span>')
198+
FALSE_MARK = mark_safe('<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>')
199+
EMPTY_MARK = mark_safe('<span class="text-muted">&mdash;</span>') # Placeholder
200+
201+
def __init__(self, *args, true_mark=TRUE_MARK, false_mark=FALSE_MARK, **kwargs):
202+
self.true_mark = true_mark
203+
self.false_mark = false_mark
204+
super().__init__(*args, **kwargs)
205+
197206
def render(self, value):
198-
if value:
199-
rendered = '<span class="text-success"><i class="mdi mdi-check-bold"></i></span>'
200-
elif value is None:
201-
rendered = '<span class="text-muted">&mdash;</span>'
202-
else:
203-
rendered = '<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>'
204-
return mark_safe(rendered)
207+
if value is None:
208+
return self.EMPTY_MARK
209+
if value and self.true_mark:
210+
return self.true_mark
211+
if not value and self.false_mark:
212+
return self.false_mark
213+
return self.EMPTY_MARK
205214

206215
def value(self, value):
207216
return str(value)

0 commit comments

Comments
 (0)