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 %}
+
+
+
+
{% endif %}
- {% plugin_right_page object %}
-
-
-
-
-
{% 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 %}
+
+
+
+
{% endif %}
- {% plugin_right_page object %}
-
-
-
-
-
{% 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' %}
-
-
-
- {% if perms.tenancy.add_contactgroup %}
-
- {% endif %}
-
{% plugin_right_page object %}
-
+
+ {% 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 %}
+
+
+
+
{% endif %}
- {% plugin_right_page object %}
-
-
-
-
-
{% 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 %}
+
+
+
+
{% endif %}
- {% plugin_right_page object %}
-
-
-
-
-
{% 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):