From d25d8c21f603ff7a4f55f6b54672e92fde4aefdd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 2 Feb 2018 17:46:23 -0500 Subject: [PATCH] Eliminated queries for distinct related object counts for better performance --- netbox/dcim/tables.py | 55 +++++++++++++++++++++++++++++----- netbox/dcim/views.py | 12 ++------ netbox/ipam/models.py | 8 ----- netbox/ipam/tables.py | 15 ++++++++-- netbox/virtualization/views.py | 5 +--- 5 files changed, 63 insertions(+), 32 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 79a356085..b9efb3a28 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -65,6 +65,10 @@ RACK_ROLE = """ {% endif %} """ +RACK_DEVICE_COUNT = """ +{{ value }} +""" + RACKRESERVATION_ACTIONS = """ {% if perms.dcim.change_rackreservation %} @@ -83,6 +87,14 @@ MANUFACTURER_ACTIONS = """ {% endif %} """ +DEVICEROLE_DEVICE_COUNT = """ +{{ value }} +""" + +DEVICEROLE_VM_COUNT = """ +{{ value }} +""" + PLATFORM_DEVICE_COUNT = """ {{ value }} """ @@ -226,12 +238,16 @@ class RackTable(BaseTable): class RackDetailTable(RackTable): - devices = tables.Column(accessor=Accessor('device_count')) + device_count = tables.TemplateColumn( + template_code=RACK_DEVICE_COUNT, + verbose_name='Devices' + ) get_utilization = tables.TemplateColumn(UTILIZATION_GRAPH, orderable=False, verbose_name='Utilization') class Meta(RackTable.Meta): fields = ( - 'pk', 'name', 'site', 'group', 'facility_id', 'tenant', 'role', 'u_height', 'devices', 'get_utilization' + 'pk', 'name', 'site', 'group', 'facility_id', 'tenant', 'role', 'u_height', 'device_count', + 'get_utilization', ) @@ -370,12 +386,25 @@ class DeviceBayTemplateTable(BaseTable): class DeviceRoleTable(BaseTable): pk = ToggleColumn() name = tables.LinkColumn(verbose_name='Name') - device_count = tables.Column(verbose_name='Devices') - vm_count = tables.Column(verbose_name='VMs') + device_count = tables.TemplateColumn( + template_code=DEVICEROLE_DEVICE_COUNT, + accessor=Accessor('devices.count'), + orderable=False, + verbose_name='Devices' + ) + vm_count = tables.TemplateColumn( + template_code=DEVICEROLE_VM_COUNT, + accessor=Accessor('virtual_machines.count'), + orderable=False, + verbose_name='VMs' + ) color = tables.TemplateColumn(COLOR_LABEL, verbose_name='Label') slug = tables.Column(verbose_name='Slug') - actions = tables.TemplateColumn(template_code=DEVICEROLE_ACTIONS, attrs={'td': {'class': 'text-right'}}, - verbose_name='') + actions = tables.TemplateColumn( + template_code=DEVICEROLE_ACTIONS, + attrs={'td': {'class': 'text-right'}}, + verbose_name='' + ) class Meta(BaseTable.Meta): model = DeviceRole @@ -388,8 +417,18 @@ class DeviceRoleTable(BaseTable): class PlatformTable(BaseTable): pk = ToggleColumn() - device_count = tables.TemplateColumn(template_code=PLATFORM_DEVICE_COUNT, verbose_name='Devices') - vm_count = tables.TemplateColumn(template_code=PLATFORM_VM_COUNT, verbose_name='VMs') + device_count = tables.TemplateColumn( + template_code=PLATFORM_DEVICE_COUNT, + accessor=Accessor('devices.count'), + orderable=False, + verbose_name='Devices' + ) + vm_count = tables.TemplateColumn( + template_code=PLATFORM_VM_COUNT, + accessor=Accessor('virtual_machines.count'), + orderable=False, + verbose_name='VMs' + ) actions = tables.TemplateColumn( template_code=PLATFORM_ACTIONS, attrs={'td': {'class': 'text-right'}}, diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index a66cee593..6ac52f58d 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -276,7 +276,7 @@ class RackListView(ObjectListView): ).prefetch_related( 'devices__device_type' ).annotate( - device_count=Count('devices', distinct=True) + device_count=Count('devices') ) filter = filters.RackFilter filter_form = forms.RackFilterForm @@ -715,10 +715,7 @@ class DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): # class DeviceRoleListView(ObjectListView): - queryset = DeviceRole.objects.annotate( - device_count=Count('devices', distinct=True), - vm_count=Count('virtual_machines', distinct=True) - ) + queryset = DeviceRole.objects.all() table = tables.DeviceRoleTable template_name = 'dcim/devicerole_list.html' @@ -756,10 +753,7 @@ class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): # class PlatformListView(ObjectListView): - queryset = Platform.objects.annotate( - device_count=Count('devices', distinct=True), - vm_count=Count('virtual_machines', distinct=True) - ) + queryset = Platform.objects.all() table = tables.PlatformTable template_name = 'dcim/platform_list.html' diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 33da470b0..3ed673c78 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -196,14 +196,6 @@ class Role(models.Model): self.weight, ) - @property - def count_prefixes(self): - return self.prefixes.count() - - @property - def count_vlans(self): - return self.vlans.count() - @python_2_unicode_compatible class Prefix(CreatedUpdatedModel, CustomFieldModel): diff --git a/netbox/ipam/tables.py b/netbox/ipam/tables.py index 9912cc566..bfc65dacc 100644 --- a/netbox/ipam/tables.py +++ b/netbox/ipam/tables.py @@ -228,9 +228,18 @@ class AggregateDetailTable(AggregateTable): class RoleTable(BaseTable): pk = ToggleColumn() - prefix_count = tables.TemplateColumn(accessor=Accessor('count_prefixes'), template_code=ROLE_PREFIX_COUNT, orderable=False, verbose_name='Prefixes') - vlan_count = tables.TemplateColumn(accessor=Accessor('count_vlans'), template_code=ROLE_VLAN_COUNT, orderable=False, verbose_name='VLANs') - slug = tables.Column(verbose_name='Slug') + prefix_count = tables.TemplateColumn( + accessor=Accessor('prefixes.count'), + template_code=ROLE_PREFIX_COUNT, + orderable=False, + verbose_name='Prefixes' + ) + vlan_count = tables.TemplateColumn( + accessor=Accessor('vlans.count'), + template_code=ROLE_VLAN_COUNT, + orderable=False, + verbose_name='VLANs' + ) actions = tables.TemplateColumn(template_code=ROLE_ACTIONS, attrs={'td': {'class': 'text-right'}}, verbose_name='') class Meta(BaseTable.Meta): diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index 6874efd16..119388dd9 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -159,10 +159,7 @@ class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView): class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): permission_required = 'virtualization.delete_cluster' cls = Cluster - queryset = Cluster.objects.annotate( - device_count=Count('devices', distinct=True), - vm_count=Count('virtual_machines', distinct=True) - ) + queryset = Cluster.objects.all() table = tables.ClusterTable default_return_url = 'virtualization:cluster_list'