diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 4806fd954..228b70bb1 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -29,6 +29,15 @@ class ProviderListView(generic.ObjectListView): class ProviderView(generic.ObjectView): queryset = Provider.objects.all() + def get_extra_context(self, request, instance): + related_models = ( + (Circuit.objects.restrict(request.user, 'view').filter(provider=instance), 'provider_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(Provider, 'edit') class ProviderEditView(generic.ObjectEditView): @@ -79,6 +88,18 @@ class ProviderNetworkListView(generic.ObjectListView): class ProviderNetworkView(generic.ObjectView): queryset = ProviderNetwork.objects.all() + def get_extra_context(self, request, instance): + related_models = ( + ( + Circuit.objects.restrict(request.user, 'view').filter(terminations__provider_network=instance), + 'providernetwork_id', + ), + ) + + return { + 'related_models': related_models, + } + @register_model_view(ProviderNetwork, 'edit') class ProviderNetworkEditView(generic.ObjectEditView): diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 4683a6084..741194712 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -21,9 +21,7 @@ from utilities.paginator import EnhancedPaginator, get_paginate_count from utilities.permissions import get_permission_for_model from utilities.utils import count_related from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin, ViewTab, register_model_view -from virtualization.filtersets import VirtualMachineFilterSet from virtualization.models import VirtualMachine -from virtualization.tables import VirtualMachineTable from . import filtersets, forms, tables from .choices import DeviceFaceChoices from .constants import NONCONNECTABLE_IFACE_TYPES @@ -359,24 +357,24 @@ class SiteView(generic.ObjectView): queryset = Site.objects.prefetch_related('tenant__group') def get_extra_context(self, request, instance): - related_models = [ + related_models = ( # DCIM - Location.objects.restrict(request.user, 'view').filter(site=instance), - Rack.objects.restrict(request.user, 'view').filter(site=instance), - Device.objects.restrict(request.user, 'view').filter(site=instance), + (Location.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'), + (Rack.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'), + (Device.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'), # Virtualization - VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=instance), + (VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=instance), 'site_id'), # IPAM - Prefix.objects.restrict(request.user, 'view').filter(site=instance), - ASN.objects.restrict(request.user, 'view').filter(sites=instance), - VLANGroup.objects.restrict(request.user, 'view').filter( + (Prefix.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'), + (ASN.objects.restrict(request.user, 'view').filter(sites=instance), 'site_id'), + (VLANGroup.objects.restrict(request.user, 'view').filter( scope_type=ContentType.objects.get_for_model(Site), scope_id=instance.pk - ), - VLAN.objects.restrict(request.user, 'view').filter(site=instance), + ), 'site_id'), + (VLAN.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'), # Circuits - Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct(), - ] + (Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct(), 'site_id'), + ) locations = Location.objects.add_related_count( Location.objects.all(), @@ -658,6 +656,11 @@ class RackView(generic.ObjectView): queryset = Rack.objects.prefetch_related('site__region', 'tenant__group', 'location', 'role') def get_extra_context(self, request, instance): + related_models = ( + (Device.objects.restrict(request.user, 'view').filter(rack=instance), 'rack_id'), + (PowerFeed.objects.restrict(request.user).filter(rack=instance), 'rack_id'), + ) + # Get 0U devices located within the rack nonracked_devices = Device.objects.filter( rack=instance, @@ -675,11 +678,6 @@ class RackView(generic.ObjectView): prev_rack = peer_racks.filter(_name__lt=instance._name).reverse().first() reservations = RackReservation.objects.restrict(request.user, 'view').filter(rack=instance) - power_feeds = PowerFeed.objects.restrict(request.user, 'view').filter(rack=instance).prefetch_related( - 'power_panel' - ) - - device_count = Device.objects.restrict(request.user, 'view').filter(rack=instance).count() # Determine any additional parameters to pass when embedding the rack elevations svg_extra = '&'.join([ @@ -687,9 +685,8 @@ class RackView(generic.ObjectView): ]) return { - 'device_count': device_count, + 'related_models': related_models, 'reservations': reservations, - 'power_feeds': power_feeds, 'nonracked_devices': nonracked_devices, 'next_rack': next_rack, 'prev_rack': prev_rack, @@ -881,10 +878,12 @@ class DeviceTypeView(generic.ObjectView): queryset = DeviceType.objects.all() def get_extra_context(self, request, instance): - instance_count = Device.objects.restrict(request.user).filter(device_type=instance).count() + related_models = ( + (Device.objects.restrict(request.user).filter(device_type=instance), 'device_type_id'), + ) return { - 'instance_count': instance_count, + 'related_models': related_models, } @@ -1119,10 +1118,12 @@ class ModuleTypeView(generic.ObjectView): queryset = ModuleType.objects.all() def get_extra_context(self, request, instance): - instance_count = Module.objects.restrict(request.user).filter(module_type=instance).count() + related_models = ( + (Module.objects.restrict(request.user).filter(module_type=instance), 'module_type_id'), + ) return { - 'instance_count': instance_count, + 'related_models': related_models, } @@ -1807,13 +1808,9 @@ class DeviceView(generic.ObjectView): vc_members = [] services = Service.objects.restrict(request.user, 'view').filter(device=instance) - vdcs = VirtualDeviceContext.objects.restrict(request.user, 'view').filter(device=instance).prefetch_related( - 'tenant' - ) return { 'services': services, - 'vdcs': vdcs, 'vc_members': vc_members, 'svg_extra': f'highlight=id:{instance.pk}' } @@ -2114,6 +2111,21 @@ class ModuleListView(generic.ObjectListView): class ModuleView(generic.ObjectView): queryset = Module.objects.all() + def get_extra_context(self, request, instance): + related_models = ( + (Interface.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (ConsolePort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (ConsoleServerPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (PowerPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (PowerOutlet.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (FrontPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + (RearPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(Module, 'edit') class ModuleEditView(generic.ObjectEditView): @@ -3436,6 +3448,15 @@ class PowerPanelListView(generic.ObjectListView): class PowerPanelView(generic.ObjectView): queryset = PowerPanel.objects.all() + def get_extra_context(self, request, instance): + related_models = ( + (PowerFeed.objects.restrict(request.user).filter(power_panel=instance), 'power_panel_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(PowerPanel, 'edit') class PowerPanelEditView(generic.ObjectEditView): @@ -3537,6 +3558,15 @@ class VirtualDeviceContextListView(generic.ObjectListView): class VirtualDeviceContextView(generic.ObjectView): queryset = VirtualDeviceContext.objects.all() + def get_extra_context(self, request, instance): + related_models = ( + (Interface.objects.restrict(request.user, 'view').filter(vdcs__in=[instance]), 'vdc_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(VirtualDeviceContext, 'edit') class VirtualDeviceContextEditView(generic.ObjectEditView): diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index bcafacc45..b7cd72d67 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -37,8 +37,10 @@ class VRFView(generic.ObjectView): queryset = VRF.objects.all() def get_extra_context(self, request, instance): - prefix_count = Prefix.objects.restrict(request.user, 'view').filter(vrf=instance).count() - ipaddress_count = IPAddress.objects.restrict(request.user, 'view').filter(vrf=instance).count() + related_models = ( + (Prefix.objects.restrict(request.user, 'view').filter(vrf=instance), 'vrf_id'), + (IPAddress.objects.restrict(request.user, 'view').filter(vrf=instance), 'vrf_id'), + ) import_targets_table = tables.RouteTargetTable( instance.import_targets.all(), @@ -50,8 +52,7 @@ class VRFView(generic.ObjectView): ) return { - 'prefix_count': prefix_count, - 'ipaddress_count': ipaddress_count, + 'related_models': related_models, 'import_targets_table': import_targets_table, 'export_targets_table': export_targets_table, } @@ -228,12 +229,13 @@ class ASNView(generic.ObjectView): queryset = ASN.objects.all() def get_extra_context(self, request, instance): - sites = instance.sites.restrict(request.user, 'view') - providers = instance.providers.restrict(request.user, 'view') + related_models = ( + (Site.objects.restrict(request.user, 'view').filter(asns__in=[instance]), 'asn_id'), + (Provider.objects.restrict(request.user, 'view').filter(asns__in=[instance]), 'asn_id'), + ) return { - 'sites_count': sites.count(), - 'providers_count': providers.count(), + 'related_models': related_models, } @@ -868,7 +870,6 @@ class VLANGroupView(generic.ObjectView): Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user)), 'tenant', 'site', 'role', ).order_by('vid') - vlans_count = vlans.count() vlans = add_available_vlans(vlans, vlan_group=instance) vlans_table = tables.VLANTable(vlans, user=request.user, exclude=('group',)) diff --git a/netbox/templates/circuits/circuittype.html b/netbox/templates/circuits/circuittype.html index 3d5ba5a6c..39c1f1541 100644 --- a/netbox/templates/circuits/circuittype.html +++ b/netbox/templates/circuits/circuittype.html @@ -35,7 +35,7 @@ {% plugin_left_page object %}
- {% include 'inc/panels/related_objects.html' %} + {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/circuits/provider.html b/netbox/templates/circuits/provider.html index 8cd7e59fb..3973d2867 100644 --- a/netbox/templates/circuits/provider.html +++ b/netbox/templates/circuits/provider.html @@ -37,21 +37,16 @@ Description {{ object.description|placeholder }} - - Circuits - - {{ object.circuits.count }} - - {% include 'inc/panels/tags.html' %} + {% include 'inc/panels/comments.html' %} {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/comments.html' %} {% include 'inc/panels/contacts.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/circuits/providernetwork.html b/netbox/templates/circuits/providernetwork.html index 29c31ab47..f478058ec 100644 --- a/netbox/templates/circuits/providernetwork.html +++ b/netbox/templates/circuits/providernetwork.html @@ -37,12 +37,13 @@ + {% include 'inc/panels/tags.html' %} {% plugin_left_page object %}
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} + {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/comments.html' %} + {% include 'inc/panels/custom_fields.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index aa31db97c..6a0d00d6d 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -157,28 +157,10 @@ {% include 'inc/panels/comments.html' %}
Virtual Device Contexts
-
- {% if vdcs %} - - - - - - - - {% for vdc in vdcs %} - - - - - - - {% endfor %} -
NameStatusIdentifierTenant
{{ vdc|linkify }}{% badge vdc.get_status_display bg_color=vdc.get_status_color %}{{ vdc.identifier|placeholder }}{{ vdc.tenant|linkify|placeholder }}
- {% else %} -
None
- {% endif %} -
+
{% if perms.dcim.add_virtualdevicecontext %}
+ {% include 'inc/panels/tags.html' %} {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} {% include 'inc/panels/comments.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/dcim/module.html b/netbox/templates/dcim/module.html index 78d5a1a05..e46bc65f5 100644 --- a/netbox/templates/dcim/module.html +++ b/netbox/templates/dcim/module.html @@ -81,104 +81,14 @@ - {% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/tags.html' %} {% include 'inc/panels/comments.html' %} {% plugin_left_page object %} - -
-
-
Components
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Interfaces - {% with component_count=object.interfaces.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Console Ports - {% with component_count=object.consoleports.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Console Server Ports - {% with component_count=object.consoleserverports.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Power Ports - {% with component_count=object.powerports.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Power Outlets - {% with component_count=object.poweroutlets.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Front Ports - {% with component_count=object.frontports.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
Rear Ports - {% with component_count=object.rearports.count %} - {% if component_count %} - {{ component_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {% endwith %} -
-
-
- {% plugin_right_page object %} +
+
+ {% include 'inc/panels/related_objects.html' %} + {% include 'inc/panels/custom_fields.html' %} + {% plugin_right_page object %}
diff --git a/netbox/templates/dcim/moduletype.html b/netbox/templates/dcim/moduletype.html index fd0148c2f..8929678b7 100644 --- a/netbox/templates/dcim/moduletype.html +++ b/netbox/templates/dcim/moduletype.html @@ -36,19 +36,16 @@ {% endif %} - - Instances - {{ instance_count }} -
- {% include 'inc/panels/custom_fields.html' %} + {% include 'inc/panels/tags.html' %} + {% include 'inc/panels/comments.html' %} {% plugin_left_page object %}
- {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/comments.html' %} + {% include 'inc/panels/related_objects.html' %} + {% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/image_attachments.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/dcim/powerpanel.html b/netbox/templates/dcim/powerpanel.html index c73e33b13..af08f3023 100644 --- a/netbox/templates/dcim/powerpanel.html +++ b/netbox/templates/dcim/powerpanel.html @@ -38,11 +38,12 @@ {% plugin_left_page object %}
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/contacts.html' %} - {% include 'inc/panels/image_attachments.html' %} - {% plugin_right_page object %} -
+ {% include 'inc/panels/related_objects.html' %} + {% include 'inc/panels/custom_fields.html' %} + {% include 'inc/panels/contacts.html' %} + {% include 'inc/panels/image_attachments.html' %} + {% plugin_right_page object %} +
diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html index e2cb1597e..c155f2796 100644 --- a/netbox/templates/dcim/rack.html +++ b/netbox/templates/dcim/rack.html @@ -90,12 +90,6 @@ Asset Tag {{ object.asset_tag|placeholder }} - - Devices - - {{ device_count }} - - Space Utilization {% utilization_graph object.get_utilization %} @@ -192,40 +186,6 @@ {% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/tags.html' %} {% include 'inc/panels/comments.html' %} - {% if power_feeds %} -
-
- Power Feeds -
-
- - - - - - - - - {% for powerfeed in power_feeds %} - - - - - - {% with power_port=powerfeed.connected_endpoints.0 %} - {% if power_port %} - - {% else %} - - {% endif %} - {% endwith %} - - {% endfor %} -
PanelFeedStatusTypeUtilization
{{ powerfeed.power_panel|linkify }}{{ powerfeed|linkify }}{% badge powerfeed.get_status_display bg_color=powerfeed.get_status_color %}{% badge powerfeed.get_type_display bg_color=powerfeed.get_type_color %}{% utilization_graph power_port.get_power_draw.allocated|percentage:powerfeed.available_power %}N/A
-
-
- {% endif %} - {% include 'inc/panels/image_attachments.html' %}
@@ -300,6 +260,7 @@
+ {% include 'inc/panels/related_objects.html' %} {% include 'dcim/inc/nonracked_devices.html' %} {% include 'inc/panels/contacts.html' %} {% plugin_right_page object %} diff --git a/netbox/templates/dcim/virtualdevicecontext.html b/netbox/templates/dcim/virtualdevicecontext.html index ee30db19e..d6e3e0c63 100644 --- a/netbox/templates/dcim/virtualdevicecontext.html +++ b/netbox/templates/dcim/virtualdevicecontext.html @@ -59,10 +59,11 @@ {% plugin_left_page object %} + {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/comments.html' %} - {% include 'inc/panels/tags.html' %} {% include 'inc/panels/custom_fields.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/ipam/asn.html b/netbox/templates/ipam/asn.html index 26903b71c..a54a0aee5 100644 --- a/netbox/templates/ipam/asn.html +++ b/netbox/templates/ipam/asn.html @@ -39,54 +39,21 @@ Description {{ object.description|placeholder }} - - Sites - - {% if sites_count %} - {{ sites_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - - - - Providers - - {% if providers_count %} - {{ providers_count }} - {% else %} - {{ ''|placeholder }} - {% endif %} - - {% plugin_left_page object %} + {% include 'inc/panels/tags.html' %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' with tags=object.tags.all url='ipam:asn_list' %} {% include 'inc/panels/comments.html' %} {% plugin_right_page object %}
-
-
Sites
-
-
-
-
Providers
-
-
{% plugin_full_width_page object %}
diff --git a/netbox/templates/ipam/vrf.html b/netbox/templates/ipam/vrf.html index b53862f9e..c365efae3 100644 --- a/netbox/templates/ipam/vrf.html +++ b/netbox/templates/ipam/vrf.html @@ -35,25 +35,14 @@ Description {{ object.description|placeholder }} - - Prefixes - - {{ prefix_count }} - - - - IP Addresses - - {{ ipaddress_count }} - - + {% include 'inc/panels/tags.html' %} {% plugin_left_page object %}
- {% include 'inc/panels/tags.html' %} + {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/comments.html' %} {% plugin_right_page object %} diff --git a/netbox/templates/virtualization/cluster.html b/netbox/templates/virtualization/cluster.html index 5f34a82c5..3dfef108b 100644 --- a/netbox/templates/virtualization/cluster.html +++ b/netbox/templates/virtualization/cluster.html @@ -44,10 +44,6 @@ Site {{ object.site|linkify|placeholder }} - - Virtual Machines - {{ object.virtual_machines.count }} -