From 91b81d51da683140ae98e393356079a7eea49608 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 25 Jan 2023 15:21:21 -0500 Subject: [PATCH] Standardize related model display for nested models --- netbox/dcim/views.py | 35 +++++++++-- netbox/templates/dcim/location.html | 22 +------ netbox/templates/dcim/region.html | 26 +++----- netbox/templates/dcim/sitegroup.html | 24 ++------ .../templates/inc/panels/related_objects.html | 4 +- netbox/templates/tenancy/contactgroup.html | 32 ++++------ netbox/templates/tenancy/tenant.html | 2 +- netbox/templates/tenancy/tenantgroup.html | 24 ++------ .../templates/wireless/wirelesslangroup.html | 24 ++------ netbox/tenancy/views.py | 60 ++++++++++++------- netbox/wireless/views.py | 10 ++++ 11 files changed, 120 insertions(+), 143 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 0edfe213c..077aa441e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -212,6 +212,18 @@ class RegionListView(generic.ObjectListView): class RegionView(generic.ObjectView): queryset = Region.objects.all() + def get_extra_context(self, request, instance): + regions = instance.get_descendants(include_self=True) + related_models = ( + (Site.objects.restrict(request.user, 'view').filter(region__in=regions), 'region_id'), + (Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'), + (Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(Region, 'edit') class RegionEditView(generic.ObjectEditView): @@ -276,6 +288,18 @@ class SiteGroupListView(generic.ObjectListView): class SiteGroupView(generic.ObjectView): queryset = SiteGroup.objects.all() + def get_extra_context(self, request, instance): + groups = instance.get_descendants(include_self=True) + related_models = ( + (Site.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'), + (Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'), + (Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(SiteGroup, 'edit') class SiteGroupEditView(generic.ObjectEditView): @@ -441,9 +465,11 @@ class LocationView(generic.ObjectView): queryset = Location.objects.all() def get_extra_context(self, request, instance): - location_ids = instance.get_descendants(include_self=True).values_list('pk', flat=True) - rack_count = Rack.objects.filter(location__in=location_ids).count() - device_count = Device.objects.filter(location__in=location_ids).count() + locations = instance.get_descendants(include_self=True) + related_models = ( + (Rack.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'), + (Device.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'), + ) nonracked_devices = Device.objects.filter( location=instance, @@ -452,8 +478,7 @@ class LocationView(generic.ObjectView): ).prefetch_related('device_type__manufacturer', 'parent_bay', 'device_role') return { - 'rack_count': rack_count, - 'device_count': device_count, + 'related_models': related_models, 'nonracked_devices': nonracked_devices.order_by('-pk')[:10], 'total_nonracked_devices_count': nonracked_devices.count(), } diff --git a/netbox/templates/dcim/location.html b/netbox/templates/dcim/location.html index 9eee5f9db..193d93f9a 100644 --- a/netbox/templates/dcim/location.html +++ b/netbox/templates/dcim/location.html @@ -56,33 +56,15 @@ {{ object.tenant|linkify|placeholder }} - - Racks - - {% if rack_count %} -
- - - -
- {% endif %} - {{ rack_count }} - - - - Devices - - {{ device_count }} - - {% include 'inc/panels/tags.html' %} + {% include 'inc/panels/custom_fields.html' %} {% plugin_left_page object %}
- {% include 'inc/panels/custom_fields.html' %} + {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/contacts.html' %} {% include 'dcim/inc/nonracked_devices.html' %} {% include 'inc/panels/image_attachments.html' %} diff --git a/netbox/templates/dcim/region.html b/netbox/templates/dcim/region.html index 2f33d5e15..85587e4b5 100644 --- a/netbox/templates/dcim/region.html +++ b/netbox/templates/dcim/region.html @@ -37,21 +37,21 @@ Parent {{ object.parent|linkify|placeholder }} - - Sites - - {{ object.sites.count }} - -
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/contacts.html' %} {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} + {% include 'inc/panels/contacts.html' %} + {% plugin_right_page object %} +
+ +
+
Child Regions
{% endif %}
- {% plugin_right_page object %} -
-
-
-
-
-
Sites
-
-
{% plugin_full_width_page object %}
diff --git a/netbox/templates/dcim/sitegroup.html b/netbox/templates/dcim/sitegroup.html index 5c117e147..2cf8e7168 100644 --- a/netbox/templates/dcim/sitegroup.html +++ b/netbox/templates/dcim/sitegroup.html @@ -37,12 +37,6 @@ Parent {{ object.parent|linkify|placeholder }} - - Sites - - {{ object.sites.count }} - -
@@ -52,6 +46,12 @@ {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} + {% plugin_right_page object %} +
+ +
+
Child Groups
{% endif %}
- {% plugin_right_page object %} -
-
-
-
-
-
Sites
-
-
{% plugin_full_width_page object %}
diff --git a/netbox/templates/inc/panels/related_objects.html b/netbox/templates/inc/panels/related_objects.html index 058d20f0e..fdc439ac6 100644 --- a/netbox/templates/inc/panels/related_objects.html +++ b/netbox/templates/inc/panels/related_objects.html @@ -3,9 +3,9 @@
@@ -44,31 +38,25 @@ {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} -
-
Child Groups
-
- {% if perms.tenancy.add_contactgroup %} - - {% endif %} -
{% plugin_right_page object %}
-
Contacts
+
Child Groups
+ {% if perms.tenancy.add_contactgroup %} + + {% endif %}
{% plugin_full_width_page object %}
diff --git a/netbox/templates/tenancy/tenant.html b/netbox/templates/tenancy/tenant.html index 92d7f51ad..da48f1ef5 100644 --- a/netbox/templates/tenancy/tenant.html +++ b/netbox/templates/tenancy/tenant.html @@ -34,7 +34,7 @@ {% plugin_left_page object %}
- {% include 'inc/panels/related_objects.html' with filter_name='tenant_id' %} + {% include 'inc/panels/related_objects.html' %} {% plugin_right_page object %}
diff --git a/netbox/templates/tenancy/tenantgroup.html b/netbox/templates/tenancy/tenantgroup.html index c026693c3..be9b3fbd0 100644 --- a/netbox/templates/tenancy/tenantgroup.html +++ b/netbox/templates/tenancy/tenantgroup.html @@ -39,12 +39,6 @@ Parent {{ object.parent|linkify|placeholder }} - - Tenants - - {{ object.tenants.count }} - - @@ -52,7 +46,13 @@ {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} + {% plugin_right_page object %} +
+ +
+
Child Groups
{% endif %}
- {% plugin_right_page object %} -
-
-
-
-
-
Tenants
-
-
{% plugin_full_width_page object %}
diff --git a/netbox/templates/wireless/wirelesslangroup.html b/netbox/templates/wireless/wirelesslangroup.html index 27072b2b0..6351804ef 100644 --- a/netbox/templates/wireless/wirelesslangroup.html +++ b/netbox/templates/wireless/wirelesslangroup.html @@ -37,12 +37,6 @@ Parent {{ object.parent|linkify|placeholder }} - - Wireless LANs - - {{ object.wirelesslans.count }} - -
@@ -50,7 +44,13 @@ {% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} + {% plugin_right_page object %} +
+ +
+
Child Groups
{% endif %}
- {% plugin_right_page object %} -
-
-
-
-
-
Wireless LANs
-
-
{% plugin_full_width_page object %}
diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index 7662efd69..93830bd55 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -35,6 +35,16 @@ class TenantGroupListView(generic.ObjectListView): class TenantGroupView(generic.ObjectView): queryset = TenantGroup.objects.all() + def get_extra_context(self, request, instance): + groups = instance.get_descendants(include_self=True) + related_models = ( + (Tenant.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(TenantGroup, 'edit') class TenantGroupEditView(generic.ObjectEditView): @@ -95,30 +105,30 @@ class TenantView(generic.ObjectView): def get_extra_context(self, request, instance): related_models = [ # DCIM - Site.objects.restrict(request.user, 'view').filter(tenant=instance), - Rack.objects.restrict(request.user, 'view').filter(tenant=instance), - RackReservation.objects.restrict(request.user, 'view').filter(tenant=instance), - Location.objects.restrict(request.user, 'view').filter(tenant=instance), - Device.objects.restrict(request.user, 'view').filter(tenant=instance), - VirtualDeviceContext.objects.restrict(request.user, 'view').filter(tenant=instance), - Cable.objects.restrict(request.user, 'view').filter(tenant=instance), + (Site.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Rack.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (RackReservation.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Location.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Device.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (VirtualDeviceContext.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Cable.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), # IPAM - VRF.objects.restrict(request.user, 'view').filter(tenant=instance), - Aggregate.objects.restrict(request.user, 'view').filter(tenant=instance), - Prefix.objects.restrict(request.user, 'view').filter(tenant=instance), - IPRange.objects.restrict(request.user, 'view').filter(tenant=instance), - IPAddress.objects.restrict(request.user, 'view').filter(tenant=instance), - ASN.objects.restrict(request.user, 'view').filter(tenant=instance), - VLAN.objects.restrict(request.user, 'view').filter(tenant=instance), - L2VPN.objects.restrict(request.user, 'view').filter(tenant=instance), + (VRF.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Aggregate.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Prefix.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (IPRange.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (IPAddress.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (ASN.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (VLAN.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (L2VPN.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), # Circuits - Circuit.objects.restrict(request.user, 'view').filter(tenant=instance), + (Circuit.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), # Virtualization - VirtualMachine.objects.restrict(request.user, 'view').filter(tenant=instance), - Cluster.objects.restrict(request.user, 'view').filter(tenant=instance), + (VirtualMachine.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (Cluster.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), # Wireless - WirelessLAN.objects.restrict(request.user, 'view').filter(tenant=instance), - WirelessLink.objects.restrict(request.user, 'view').filter(tenant=instance), + (WirelessLAN.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), + (WirelessLink.objects.restrict(request.user, 'view').filter(tenant=instance), 'tenant_id'), ] return { @@ -177,6 +187,16 @@ class ContactGroupListView(generic.ObjectListView): class ContactGroupView(generic.ObjectView): queryset = ContactGroup.objects.all() + def get_extra_context(self, request, instance): + groups = instance.get_descendants(include_self=True) + related_models = ( + (Contact.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(ContactGroup, 'edit') class ContactGroupEditView(generic.ObjectEditView): diff --git a/netbox/wireless/views.py b/netbox/wireless/views.py index 8665ed988..22b1ff15d 100644 --- a/netbox/wireless/views.py +++ b/netbox/wireless/views.py @@ -27,6 +27,16 @@ class WirelessLANGroupListView(generic.ObjectListView): class WirelessLANGroupView(generic.ObjectView): queryset = WirelessLANGroup.objects.all() + def get_extra_context(self, request, instance): + groups = instance.get_descendants(include_self=True) + related_models = ( + (WirelessLAN.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'), + ) + + return { + 'related_models': related_models, + } + @register_model_view(WirelessLANGroup, 'edit') class WirelessLANGroupEditView(generic.ObjectEditView):