From e5553e19498ee4be08a346217e6c135679a96a32 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 2 Apr 2026 11:30:23 -0400 Subject: [PATCH] Introduce should_render() method on Panel class --- netbox/dcim/ui/panels.py | 36 +++++++++++++----------------------- netbox/ipam/ui/panels.py | 6 ++---- netbox/netbox/ui/panels.py | 21 ++++++++++++++------- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/netbox/dcim/ui/panels.py b/netbox/dcim/ui/panels.py index 6edfd9b64..4249b98fb 100644 --- a/netbox/dcim/ui/panels.py +++ b/netbox/dcim/ui/panels.py @@ -442,10 +442,8 @@ class VirtualChassisMembersPanel(panels.ObjectPanel): 'vc_members': context.get('vc_members'), } - def render(self, context): - if not context.get('vc_members'): - return '' - return super().render(context) + def should_render(self, context): + return bool(context.get('vc_members')) class PowerUtilizationPanel(panels.ObjectPanel): @@ -461,11 +459,9 @@ class PowerUtilizationPanel(panels.ObjectPanel): 'vc_members': context.get('vc_members'), } - def render(self, context): + def should_render(self, context): obj = context['object'] - if not obj.powerports.exists() or not obj.poweroutlets.exists(): - return '' - return super().render(context) + return obj.powerports.exists() and obj.poweroutlets.exists() class InterfacePanel(panels.ObjectAttributesPanel): @@ -518,11 +514,9 @@ class InterfaceConnectionPanel(panels.ObjectPanel): template_name = 'dcim/panels/interface_connection.html' title = _('Connection') - def render(self, context): + def should_render(self, context): obj = context.get('object') - if obj and obj.is_virtual: - return '' - return super().render(context) + return False if (obj is None or obj.is_virtual) else True class VirtualCircuitPanel(panels.ObjectPanel): @@ -532,11 +526,11 @@ class VirtualCircuitPanel(panels.ObjectPanel): template_name = 'dcim/panels/interface_virtual_circuit.html' title = _('Virtual Circuit') - def render(self, context): + def should_render(self, context): obj = context.get('object') if not obj or not obj.is_virtual or not hasattr(obj, 'virtual_circuit_termination'): - return '' - return super().render(context) + return False + return True class InterfaceWirelessPanel(panels.ObjectPanel): @@ -546,11 +540,9 @@ class InterfaceWirelessPanel(panels.ObjectPanel): template_name = 'dcim/panels/interface_wireless.html' title = _('Wireless') - def render(self, context): + def should_render(self, context): obj = context.get('object') - if not obj or not obj.is_wireless: - return '' - return super().render(context) + return False if (obj is None or not obj.is_wireless) else True class WirelessLANsPanel(panels.ObjectPanel): @@ -560,8 +552,6 @@ class WirelessLANsPanel(panels.ObjectPanel): template_name = 'dcim/panels/interface_wireless_lans.html' title = _('Wireless LANs') - def render(self, context): + def should_render(self, context): obj = context.get('object') - if not obj or not obj.is_wireless: - return '' - return super().render(context) + return False if (obj is None or not obj.is_wireless) else True diff --git a/netbox/ipam/ui/panels.py b/netbox/ipam/ui/panels.py index 06e429967..c8984352a 100644 --- a/netbox/ipam/ui/panels.py +++ b/netbox/ipam/ui/panels.py @@ -229,11 +229,9 @@ class VLANCustomerVLANsPanel(panels.ObjectsTablePanel): ], ) - def render(self, context): + def should_render(self, context): obj = context.get('object') - if not obj or obj.qinq_role != 'svlan': - return '' - return super().render(context) + return False if (obj is None or obj.qinq_role != 'svlan') else True class ServiceTemplatePanel(panels.ObjectAttributesPanel): diff --git a/netbox/netbox/ui/panels.py b/netbox/netbox/ui/panels.py index 67290014f..79b576fd9 100644 --- a/netbox/netbox/ui/panels.py +++ b/netbox/netbox/ui/panels.py @@ -74,6 +74,15 @@ class Panel: 'panel_class': self.__class__.__name__, } + def should_render(self, context): + """ + Determines whether the panel should render on the page. (Default: True) + + Parameters: + context (dict): The template context + """ + return True + def render(self, context): """ Render the panel as HTML. @@ -81,6 +90,8 @@ class Panel: Parameters: context (dict): The template context """ + if not self.should_render(context): + return '' ctx = self.get_context(context) return render_to_string(self.template_name, ctx, request=ctx.get('request')) @@ -405,14 +416,10 @@ class ContextTablePanel(ObjectPanel): return context.get(self.table) def get_context(self, context): - table = self._resolve_table(context) return { **super().get_context(context), - 'table': table, + 'table': self._resolve_table(context), } - def render(self, context): - table = self._resolve_table(context) - if table is None: - return '' - return super().render(context) + def should_render(self, context): + return context.get('table') is not None