From 71d3dc6e44638140d03542cd232c85afb66e42a6 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 10 Feb 2022 16:29:19 -0500 Subject: [PATCH] Improve ChoiceFieldColumn to not rely on model method to derive label color --- docs/plugins/development/tables.md | 6 ++++++ netbox/circuits/models/circuits.py | 3 --- netbox/dcim/models/cables.py | 3 --- netbox/dcim/models/devices.py | 3 --- netbox/dcim/models/power.py | 6 ------ netbox/dcim/models/racks.py | 3 --- netbox/dcim/models/sites.py | 3 --- netbox/extras/models/change_logging.py | 3 --- netbox/extras/models/models.py | 3 --- netbox/ipam/models/ip.py | 12 ------------ netbox/ipam/models/vlans.py | 3 --- netbox/netbox/tables/columns.py | 23 +++++++++++++---------- netbox/virtualization/models.py | 3 --- netbox/wireless/models.py | 3 --- 14 files changed, 19 insertions(+), 58 deletions(-) diff --git a/docs/plugins/development/tables.md b/docs/plugins/development/tables.md index 393df48a9..6d1ac2289 100644 --- a/docs/plugins/development/tables.md +++ b/docs/plugins/development/tables.md @@ -57,6 +57,12 @@ The table column classes listed below are supported for use in plugins. These cl selection: members: false +::: netbox.tables.ChoiceFieldColumn + rendering: + show_source: false + selection: + members: false + ::: netbox.tables.ColorColumn rendering: show_source: false diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 0f3de91ed..b2d9d85a0 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -132,9 +132,6 @@ class Circuit(NetBoxModel): def get_absolute_url(self): return reverse('circuits:circuit', args=[self.pk]) - def get_status_class(self): - return CircuitStatusChoices.colors.get(self.status, 'secondary') - class CircuitTermination(WebhooksMixin, ChangeLoggedModel, LinkTermination): circuit = models.ForeignKey( diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index 0d46d3c8f..0d5c50622 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -286,9 +286,6 @@ class Cable(NetBoxModel): # Update the private pk used in __str__ in case this is a new object (i.e. just got its pk) self._pk = self.pk - def get_status_class(self): - return LinkStatusChoices.colors.get(self.status) - def get_compatible_types(self): """ Return all termination types compatible with termination A. diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index f721f90c2..9e2c30103 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -1001,9 +1001,6 @@ class Device(NetBoxModel, ConfigContextModel): """ return Device.objects.filter(parent_bay__device=self.pk) - def get_status_class(self): - return DeviceStatusChoices.colors.get(self.status, 'secondary') - class Module(NetBoxModel, ConfigContextModel): """ diff --git a/netbox/dcim/models/power.py b/netbox/dcim/models/power.py index bbbdda83c..2a7cba1fe 100644 --- a/netbox/dcim/models/power.py +++ b/netbox/dcim/models/power.py @@ -169,9 +169,3 @@ class PowerFeed(NetBoxModel, PathEndpoint, LinkTermination): @property def parent_object(self): return self.power_panel - - def get_type_class(self): - return PowerFeedTypeChoices.colors.get(self.type) - - def get_status_class(self): - return PowerFeedStatusChoices.colors.get(self.status, 'secondary') diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index 0fe84aa0c..15aeee4ca 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -247,9 +247,6 @@ class Rack(NetBoxModel): else: return reversed(range(1, self.u_height + 1)) - def get_status_class(self): - return RackStatusChoices.colors.get(self.status, 'secondary') - def get_rack_units(self, user=None, face=DeviceFaceChoices.FACE_FRONT, exclude=None, expand_devices=True): """ Return a list of rack units as dictionaries. Example: {'device': None, 'face': 0, 'id': 48, 'name': 'U48'} diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py index 625422d6b..b06fad4f0 100644 --- a/netbox/dcim/models/sites.py +++ b/netbox/dcim/models/sites.py @@ -309,9 +309,6 @@ class Site(NetBoxModel): def get_absolute_url(self): return reverse('dcim:site', args=[self.pk]) - def get_status_class(self): - return SiteStatusChoices.colors.get(self.status, 'secondary') - # # Locations diff --git a/netbox/extras/models/change_logging.py b/netbox/extras/models/change_logging.py index 8444260c8..c7ad44985 100644 --- a/netbox/extras/models/change_logging.py +++ b/netbox/extras/models/change_logging.py @@ -102,6 +102,3 @@ class ObjectChange(models.Model): def get_absolute_url(self): return reverse('extras:objectchange', args=[self.pk]) - - def get_action_class(self): - return ObjectChangeActionChoices.colors.get(self.action) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 9cbacca6a..77ba66377 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -458,9 +458,6 @@ class JournalEntry(WebhooksMixin, ChangeLoggedModel): def get_absolute_url(self): return reverse('extras:journalentry', args=[self.pk]) - def get_kind_class(self): - return JournalEntryKindChoices.colors.get(self.kind) - class JobResult(models.Model): """ diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 1354c6e64..a6e6967f1 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -437,9 +437,6 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel): self.prefix.prefixlen = value prefix_length = property(fset=_set_prefix_length) - def get_status_class(self): - return PrefixStatusChoices.colors.get(self.status, 'secondary') - def get_parents(self, include_self=False): """ Return all containing Prefixes in the hierarchy. @@ -706,9 +703,6 @@ class IPRange(NetBoxModel): self.end_address.prefixlen = value prefix_length = property(fset=_set_prefix_length) - def get_status_class(self): - return IPRangeStatusChoices.colors.get(self.status, 'secondary') - def get_child_ips(self): """ Return all IPAddresses within this IPRange and VRF. @@ -922,9 +916,3 @@ class IPAddress(NetBoxModel): if self.address is not None: self.address.prefixlen = value mask_length = property(fset=_set_mask_length) - - def get_status_class(self): - return IPAddressStatusChoices.colors.get(self.status, 'secondary') - - def get_role_class(self): - return IPAddressRoleChoices.colors.get(self.role) diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 7cd03ed55..4673c8f45 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -211,9 +211,6 @@ class VLAN(NetBoxModel): f"{self.group}" }) - def get_status_class(self): - return VLANStatusChoices.colors.get(self.status, 'secondary') - def get_interfaces(self): # Return all device interfaces assigned to this VLAN return Interface.objects.filter( diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 43350acb0..fa8c3d7cf 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -167,18 +167,21 @@ class ActionsColumn(tables.Column): class ChoiceFieldColumn(tables.Column): """ - Render a ChoiceField value inside a indicating a particular CSS class. This is useful for displaying colored - choices. The CSS class is derived by calling .get_FOO_class() on the row record. + Render a model's static ChoiceField with its value from `get_FOO_display()` as a colored badge. Colors are derived + from the ChoiceSet associated with the model field. """ def render(self, record, bound_column, value): - if value: - name = bound_column.name - css_class = getattr(record, f'get_{name}_class')() - label = getattr(record, f'get_{name}_display')() - return mark_safe( - f'{label}' - ) - return self.default + if value in self.empty_values: + return self.default + + accessor = tables.A(bound_column.accessor) + field = accessor.get_field(record) + raw_value = accessor.resolve(record) # `value` is from get_FOO_display() + + # Determine the background color to use + bg_color = field.choices.colors.get(raw_value, 'secondary') + + return mark_safe(f'{value}') def value(self, value): return value diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index 42d333d55..5e41064c4 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -322,9 +322,6 @@ class VirtualMachine(NetBoxModel, ConfigContextModel): field: f"The specified IP address ({ip}) is not assigned to this VM.", }) - def get_status_class(self): - return VirtualMachineStatusChoices.colors.get(self.status, 'secondary') - @property def primary_ip(self): if get_config().PREFER_IPV4 and self.primary_ip4: diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index fc80e91df..055ea1672 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -177,9 +177,6 @@ class WirelessLink(WirelessAuthenticationBase, NetBoxModel): def get_absolute_url(self): return reverse('wireless:wirelesslink', args=[self.pk]) - def get_status_class(self): - return LinkStatusChoices.colors.get(self.status) - def clean(self): # Validate interface types