Просмотр исходного кода

Rename get_subquery() to count_related()

Jeremy Stretch 5 лет назад
Родитель
Сommit
4a066a1913

+ 3 - 3
netbox/circuits/api/views.py

@@ -6,7 +6,7 @@ from circuits.models import Provider, CircuitTermination, CircuitType, Circuit
 from dcim.api.views import PathEndpointMixin
 from extras.api.views import CustomFieldModelViewSet
 from netbox.api.views import ModelViewSet
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import serializers
 
 
@@ -24,7 +24,7 @@ class CircuitsRootView(APIRootView):
 
 class ProviderViewSet(CustomFieldModelViewSet):
     queryset = Provider.objects.prefetch_related('tags').annotate(
-        circuit_count=get_subquery(Circuit, 'provider')
+        circuit_count=count_related(Circuit, 'provider')
     )
     serializer_class = serializers.ProviderSerializer
     filterset_class = filters.ProviderFilterSet
@@ -36,7 +36,7 @@ class ProviderViewSet(CustomFieldModelViewSet):
 
 class CircuitTypeViewSet(ModelViewSet):
     queryset = CircuitType.objects.annotate(
-        circuit_count=get_subquery(Circuit, 'type')
+        circuit_count=count_related(Circuit, 'type')
     )
     serializer_class = serializers.CircuitTypeSerializer
     filterset_class = filters.CircuitTypeFilterSet

+ 6 - 6
netbox/circuits/views.py

@@ -6,7 +6,7 @@ from django_tables2 import RequestConfig
 from netbox.views import generic
 from utilities.forms import ConfirmationForm
 from utilities.paginator import EnhancedPaginator, get_paginate_count
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import filters, forms, tables
 from .choices import CircuitTerminationSideChoices
 from .models import Circuit, CircuitTermination, CircuitType, Provider
@@ -18,7 +18,7 @@ from .models import Circuit, CircuitTermination, CircuitType, Provider
 
 class ProviderListView(generic.ObjectListView):
     queryset = Provider.objects.annotate(
-        count_circuits=get_subquery(Circuit, 'provider')
+        count_circuits=count_related(Circuit, 'provider')
     )
     filterset = filters.ProviderFilterSet
     filterset_form = forms.ProviderFilterForm
@@ -67,7 +67,7 @@ class ProviderBulkImportView(generic.BulkImportView):
 
 class ProviderBulkEditView(generic.BulkEditView):
     queryset = Provider.objects.annotate(
-        count_circuits=get_subquery(Circuit, 'provider')
+        count_circuits=count_related(Circuit, 'provider')
     )
     filterset = filters.ProviderFilterSet
     table = tables.ProviderTable
@@ -76,7 +76,7 @@ class ProviderBulkEditView(generic.BulkEditView):
 
 class ProviderBulkDeleteView(generic.BulkDeleteView):
     queryset = Provider.objects.annotate(
-        count_circuits=get_subquery(Circuit, 'provider')
+        count_circuits=count_related(Circuit, 'provider')
     )
     filterset = filters.ProviderFilterSet
     table = tables.ProviderTable
@@ -88,7 +88,7 @@ class ProviderBulkDeleteView(generic.BulkDeleteView):
 
 class CircuitTypeListView(generic.ObjectListView):
     queryset = CircuitType.objects.annotate(
-        circuit_count=get_subquery(Circuit, 'type')
+        circuit_count=count_related(Circuit, 'type')
     )
     table = tables.CircuitTypeTable
 
@@ -110,7 +110,7 @@ class CircuitTypeBulkImportView(generic.BulkImportView):
 
 class CircuitTypeBulkDeleteView(generic.BulkDeleteView):
     queryset = CircuitType.objects.annotate(
-        circuit_count=get_subquery(Circuit, 'type')
+        circuit_count=count_related(Circuit, 'type')
     )
     table = tables.CircuitTypeTable
 

+ 20 - 20
netbox/dcim/api/views.py

@@ -30,7 +30,7 @@ from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
 from netbox.api.exceptions import ServiceUnavailable
 from netbox.api.metadata import ContentTypeMetadata
 from utilities.api import get_serializer_for_model
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from virtualization.models import VirtualMachine
 from . import serializers
 from .exceptions import MissingFilterException
@@ -119,12 +119,12 @@ class SiteViewSet(CustomFieldModelViewSet):
     queryset = Site.objects.prefetch_related(
         'region', 'tenant', 'tags'
     ).annotate(
-        device_count=get_subquery(Device, 'site'),
-        rack_count=get_subquery(Rack, 'site'),
-        prefix_count=get_subquery(Prefix, 'site'),
-        vlan_count=get_subquery(VLAN, 'site'),
-        circuit_count=get_subquery(Circuit, 'terminations__site'),
-        virtualmachine_count=get_subquery(VirtualMachine, 'cluster__site')
+        device_count=count_related(Device, 'site'),
+        rack_count=count_related(Rack, 'site'),
+        prefix_count=count_related(Prefix, 'site'),
+        vlan_count=count_related(VLAN, 'site'),
+        circuit_count=count_related(Circuit, 'terminations__site'),
+        virtualmachine_count=count_related(VirtualMachine, 'cluster__site')
     )
     serializer_class = serializers.SiteSerializer
     filterset_class = filters.SiteFilterSet
@@ -152,7 +152,7 @@ class RackGroupViewSet(ModelViewSet):
 
 class RackRoleViewSet(ModelViewSet):
     queryset = RackRole.objects.annotate(
-        rack_count=get_subquery(Rack, 'role')
+        rack_count=count_related(Rack, 'role')
     )
     serializer_class = serializers.RackRoleSerializer
     filterset_class = filters.RackRoleFilterSet
@@ -166,8 +166,8 @@ class RackViewSet(CustomFieldModelViewSet):
     queryset = Rack.objects.prefetch_related(
         'site', 'group__site', 'role', 'tenant', 'tags'
     ).annotate(
-        device_count=get_subquery(Device, 'rack'),
-        powerfeed_count=get_subquery(PowerFeed, 'rack')
+        device_count=count_related(Device, 'rack'),
+        powerfeed_count=count_related(PowerFeed, 'rack')
     )
     serializer_class = serializers.RackSerializer
     filterset_class = filters.RackFilterSet
@@ -240,9 +240,9 @@ class RackReservationViewSet(ModelViewSet):
 
 class ManufacturerViewSet(ModelViewSet):
     queryset = Manufacturer.objects.annotate(
-        devicetype_count=get_subquery(DeviceType, 'manufacturer'),
-        inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'),
-        platform_count=get_subquery(Platform, 'manufacturer')
+        devicetype_count=count_related(DeviceType, 'manufacturer'),
+        inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
+        platform_count=count_related(Platform, 'manufacturer')
     )
     serializer_class = serializers.ManufacturerSerializer
     filterset_class = filters.ManufacturerFilterSet
@@ -254,7 +254,7 @@ class ManufacturerViewSet(ModelViewSet):
 
 class DeviceTypeViewSet(CustomFieldModelViewSet):
     queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate(
-        device_count=get_subquery(Device, 'device_type')
+        device_count=count_related(Device, 'device_type')
     )
     serializer_class = serializers.DeviceTypeSerializer
     filterset_class = filters.DeviceTypeFilterSet
@@ -318,8 +318,8 @@ class DeviceBayTemplateViewSet(ModelViewSet):
 
 class DeviceRoleViewSet(ModelViewSet):
     queryset = DeviceRole.objects.annotate(
-        device_count=get_subquery(Device, 'device_role'),
-        virtualmachine_count=get_subquery(VirtualMachine, 'role')
+        device_count=count_related(Device, 'device_role'),
+        virtualmachine_count=count_related(VirtualMachine, 'role')
     )
     serializer_class = serializers.DeviceRoleSerializer
     filterset_class = filters.DeviceRoleFilterSet
@@ -331,8 +331,8 @@ class DeviceRoleViewSet(ModelViewSet):
 
 class PlatformViewSet(ModelViewSet):
     queryset = Platform.objects.annotate(
-        device_count=get_subquery(Device, 'platform'),
-        virtualmachine_count=get_subquery(VirtualMachine, 'platform')
+        device_count=count_related(Device, 'platform'),
+        virtualmachine_count=count_related(VirtualMachine, 'platform')
     )
     serializer_class = serializers.PlatformSerializer
     filterset_class = filters.PlatformFilterSet
@@ -596,7 +596,7 @@ class CableViewSet(ModelViewSet):
 
 class VirtualChassisViewSet(ModelViewSet):
     queryset = VirtualChassis.objects.prefetch_related('tags').annotate(
-        member_count=get_subquery(Device, 'virtual_chassis')
+        member_count=count_related(Device, 'virtual_chassis')
     )
     serializer_class = serializers.VirtualChassisSerializer
     filterset_class = filters.VirtualChassisFilterSet
@@ -610,7 +610,7 @@ class PowerPanelViewSet(ModelViewSet):
     queryset = PowerPanel.objects.prefetch_related(
         'site', 'rack_group'
     ).annotate(
-        powerfeed_count=get_subquery(PowerFeed, 'power_panel')
+        powerfeed_count=count_related(PowerFeed, 'power_panel')
     )
     serializer_class = serializers.PowerPanelSerializer
     filterset_class = filters.PowerPanelFilterSet

+ 18 - 18
netbox/dcim/views.py

@@ -20,7 +20,7 @@ from secrets.models import Secret
 from utilities.forms import ConfirmationForm
 from utilities.paginator import EnhancedPaginator, get_paginate_count
 from utilities.permissions import get_permission_for_model
-from utilities.utils import csv_format, get_subquery
+from utilities.utils import csv_format, count_related
 from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
 from virtualization.models import VirtualMachine
 from . import filters, forms, tables
@@ -254,7 +254,7 @@ class RackGroupBulkDeleteView(generic.BulkDeleteView):
 
 class RackRoleListView(generic.ObjectListView):
     queryset = RackRole.objects.annotate(
-        rack_count=get_subquery(Rack, 'role')
+        rack_count=count_related(Rack, 'role')
     )
     table = tables.RackRoleTable
 
@@ -276,7 +276,7 @@ class RackRoleBulkImportView(generic.BulkImportView):
 
 class RackRoleBulkDeleteView(generic.BulkDeleteView):
     queryset = RackRole.objects.annotate(
-        rack_count=get_subquery(Rack, 'role')
+        rack_count=count_related(Rack, 'role')
     )
     table = tables.RackRoleTable
 
@@ -289,7 +289,7 @@ class RackListView(generic.ObjectListView):
     queryset = Rack.objects.prefetch_related(
         'site', 'group', 'tenant', 'role', 'devices__device_type'
     ).annotate(
-        device_count=get_subquery(Device, 'rack')
+        device_count=count_related(Device, 'rack')
     )
     filterset = filters.RackFilterSet
     filterset_form = forms.RackFilterForm
@@ -470,9 +470,9 @@ class RackReservationBulkDeleteView(generic.BulkDeleteView):
 
 class ManufacturerListView(generic.ObjectListView):
     queryset = Manufacturer.objects.annotate(
-        devicetype_count=get_subquery(DeviceType, 'manufacturer'),
-        inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'),
-        platform_count=get_subquery(Platform, 'manufacturer')
+        devicetype_count=count_related(DeviceType, 'manufacturer'),
+        inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
+        platform_count=count_related(Platform, 'manufacturer')
     )
     table = tables.ManufacturerTable
 
@@ -494,7 +494,7 @@ class ManufacturerBulkImportView(generic.BulkImportView):
 
 class ManufacturerBulkDeleteView(generic.BulkDeleteView):
     queryset = Manufacturer.objects.annotate(
-        devicetype_count=get_subquery(DeviceType, 'manufacturer')
+        devicetype_count=count_related(DeviceType, 'manufacturer')
     )
     table = tables.ManufacturerTable
 
@@ -505,7 +505,7 @@ class ManufacturerBulkDeleteView(generic.BulkDeleteView):
 
 class DeviceTypeListView(generic.ObjectListView):
     queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
-        instance_count=get_subquery(Device, 'device_type')
+        instance_count=count_related(Device, 'device_type')
     )
     filterset = filters.DeviceTypeFilterSet
     filterset_form = forms.DeviceTypeFilterForm
@@ -612,7 +612,7 @@ class DeviceTypeImportView(generic.ObjectImportView):
 
 class DeviceTypeBulkEditView(generic.BulkEditView):
     queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
-        instance_count=get_subquery(Device, 'device_type')
+        instance_count=count_related(Device, 'device_type')
     )
     filterset = filters.DeviceTypeFilterSet
     table = tables.DeviceTypeTable
@@ -621,7 +621,7 @@ class DeviceTypeBulkEditView(generic.BulkEditView):
 
 class DeviceTypeBulkDeleteView(generic.BulkDeleteView):
     queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
-        instance_count=get_subquery(Device, 'device_type')
+        instance_count=count_related(Device, 'device_type')
     )
     filterset = filters.DeviceTypeFilterSet
     table = tables.DeviceTypeTable
@@ -913,8 +913,8 @@ class DeviceBayTemplateBulkDeleteView(generic.BulkDeleteView):
 
 class DeviceRoleListView(generic.ObjectListView):
     queryset = DeviceRole.objects.annotate(
-        device_count=get_subquery(Device, 'device_role'),
-        vm_count=get_subquery(VirtualMachine, 'role')
+        device_count=count_related(Device, 'device_role'),
+        vm_count=count_related(VirtualMachine, 'role')
     )
     table = tables.DeviceRoleTable
 
@@ -945,8 +945,8 @@ class DeviceRoleBulkDeleteView(generic.BulkDeleteView):
 
 class PlatformListView(generic.ObjectListView):
     queryset = Platform.objects.annotate(
-        device_count=get_subquery(Device, 'platform'),
-        vm_count=get_subquery(VirtualMachine, 'platform')
+        device_count=count_related(Device, 'platform'),
+        vm_count=count_related(VirtualMachine, 'platform')
     )
     table = tables.PlatformTable
 
@@ -2335,7 +2335,7 @@ class InterfaceConnectionsListView(generic.ObjectListView):
 
 class VirtualChassisListView(generic.ObjectListView):
     queryset = VirtualChassis.objects.prefetch_related('master').annotate(
-        member_count=get_subquery(Device, 'virtual_chassis')
+        member_count=count_related(Device, 'virtual_chassis')
     )
     table = tables.VirtualChassisTable
     filterset = filters.VirtualChassisFilterSet
@@ -2565,7 +2565,7 @@ class PowerPanelListView(generic.ObjectListView):
     queryset = PowerPanel.objects.prefetch_related(
         'site', 'rack_group'
     ).annotate(
-        powerfeed_count=get_subquery(PowerFeed, 'power_panel')
+        powerfeed_count=count_related(PowerFeed, 'power_panel')
     )
     filterset = filters.PowerPanelFilterSet
     filterset_form = forms.PowerPanelFilterForm
@@ -2615,7 +2615,7 @@ class PowerPanelBulkDeleteView(generic.BulkDeleteView):
     queryset = PowerPanel.objects.prefetch_related(
         'site', 'rack_group'
     ).annotate(
-        powerfeed_count=get_subquery(PowerFeed, 'power_panel')
+        powerfeed_count=count_related(PowerFeed, 'power_panel')
     )
     filterset = filters.PowerPanelFilterSet
     table = tables.PowerPanelTable

+ 2 - 2
netbox/extras/api/views.py

@@ -21,7 +21,7 @@ from netbox.api.authentication import IsAuthenticatedOrLoginNotRequired
 from netbox.api.metadata import ContentTypeMetadata
 from netbox.api.views import ModelViewSet
 from utilities.exceptions import RQWorkerNotRunningException
-from utilities.utils import copy_safe_request, get_subquery
+from utilities.utils import copy_safe_request, count_related
 from . import serializers
 
 
@@ -102,7 +102,7 @@ class ExportTemplateViewSet(ModelViewSet):
 
 class TagViewSet(ModelViewSet):
     queryset = Tag.objects.annotate(
-        tagged_items=get_subquery(TaggedItem, 'tag')
+        tagged_items=count_related(TaggedItem, 'tag')
     )
     serializer_class = serializers.TagSerializer
     filterset_class = filters.TagFilterSet

+ 4 - 4
netbox/extras/views.py

@@ -12,7 +12,7 @@ from rq import Worker
 from netbox.views import generic
 from utilities.forms import ConfirmationForm
 from utilities.paginator import EnhancedPaginator, get_paginate_count
-from utilities.utils import copy_safe_request, get_subquery, shallow_compare_dict
+from utilities.utils import copy_safe_request, count_related, shallow_compare_dict
 from utilities.views import ContentTypePermissionRequiredMixin
 from . import filters, forms, tables
 from .choices import JobResultStatusChoices
@@ -27,7 +27,7 @@ from .scripts import get_scripts, run_script
 
 class TagListView(generic.ObjectListView):
     queryset = Tag.objects.annotate(
-        items=get_subquery(TaggedItem, 'tag')
+        items=count_related(TaggedItem, 'tag')
     )
     filterset = filters.TagFilterSet
     filterset_form = forms.TagFilterForm
@@ -52,7 +52,7 @@ class TagBulkImportView(generic.BulkImportView):
 
 class TagBulkEditView(generic.BulkEditView):
     queryset = Tag.objects.annotate(
-        items=get_subquery(TaggedItem, 'tag')
+        items=count_related(TaggedItem, 'tag')
     )
     table = tables.TagTable
     form = forms.TagBulkEditForm
@@ -60,7 +60,7 @@ class TagBulkEditView(generic.BulkEditView):
 
 class TagBulkDeleteView(generic.BulkDeleteView):
     queryset = Tag.objects.annotate(
-        items=get_subquery(TaggedItem, 'tag')
+        items=count_related(TaggedItem, 'tag')
     )
     table = tables.TagTable
 

+ 8 - 8
netbox/ipam/api/views.py

@@ -12,7 +12,7 @@ from ipam import filters
 from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, RouteTarget, Service, VLAN, VLANGroup, VRF
 from netbox.api.views import ModelViewSet
 from utilities.constants import ADVISORY_LOCK_KEYS
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import serializers
 
 
@@ -32,8 +32,8 @@ class VRFViewSet(CustomFieldModelViewSet):
     queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
         'import_targets', 'export_targets', 'tags'
     ).annotate(
-        ipaddress_count=get_subquery(IPAddress, 'vrf'),
-        prefix_count=get_subquery(Prefix, 'vrf')
+        ipaddress_count=count_related(IPAddress, 'vrf'),
+        prefix_count=count_related(Prefix, 'vrf')
     )
     serializer_class = serializers.VRFSerializer
     filterset_class = filters.VRFFilterSet
@@ -55,7 +55,7 @@ class RouteTargetViewSet(CustomFieldModelViewSet):
 
 class RIRViewSet(ModelViewSet):
     queryset = RIR.objects.annotate(
-        aggregate_count=get_subquery(Aggregate, 'rir')
+        aggregate_count=count_related(Aggregate, 'rir')
     )
     serializer_class = serializers.RIRSerializer
     filterset_class = filters.RIRFilterSet
@@ -77,8 +77,8 @@ class AggregateViewSet(CustomFieldModelViewSet):
 
 class RoleViewSet(ModelViewSet):
     queryset = Role.objects.annotate(
-        prefix_count=get_subquery(Prefix, 'role'),
-        vlan_count=get_subquery(VLAN, 'role')
+        prefix_count=count_related(Prefix, 'role'),
+        vlan_count=count_related(VLAN, 'role')
     )
     serializer_class = serializers.RoleSerializer
     filterset_class = filters.RoleFilterSet
@@ -272,7 +272,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
 
 class VLANGroupViewSet(ModelViewSet):
     queryset = VLANGroup.objects.prefetch_related('site').annotate(
-        vlan_count=get_subquery(VLAN, 'group')
+        vlan_count=count_related(VLAN, 'group')
     )
     serializer_class = serializers.VLANGroupSerializer
     filterset_class = filters.VLANGroupFilterSet
@@ -286,7 +286,7 @@ class VLANViewSet(CustomFieldModelViewSet):
     queryset = VLAN.objects.prefetch_related(
         'site', 'group', 'tenant', 'role', 'tags'
     ).annotate(
-        prefix_count=get_subquery(Prefix, 'vlan')
+        prefix_count=count_related(Prefix, 'vlan')
     )
     serializer_class = serializers.VLANSerializer
     filterset_class = filters.VLANFilterSet

+ 7 - 7
netbox/ipam/views.py

@@ -6,7 +6,7 @@ from django_tables2 import RequestConfig
 from dcim.models import Device, Interface
 from netbox.views import generic
 from utilities.paginator import EnhancedPaginator, get_paginate_count
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from virtualization.models import VirtualMachine, VMInterface
 from . import filters, forms, tables
 from .constants import *
@@ -140,7 +140,7 @@ class RouteTargetBulkDeleteView(generic.BulkDeleteView):
 
 class RIRListView(generic.ObjectListView):
     queryset = RIR.objects.annotate(
-        aggregate_count=get_subquery(Aggregate, 'rir')
+        aggregate_count=count_related(Aggregate, 'rir')
     )
     filterset = filters.RIRFilterSet
     filterset_form = forms.RIRFilterForm
@@ -165,7 +165,7 @@ class RIRBulkImportView(generic.BulkImportView):
 
 class RIRBulkDeleteView(generic.BulkDeleteView):
     queryset = RIR.objects.annotate(
-        aggregate_count=get_subquery(Aggregate, 'rir')
+        aggregate_count=count_related(Aggregate, 'rir')
     )
     filterset = filters.RIRFilterSet
     table = tables.RIRTable
@@ -277,8 +277,8 @@ class AggregateBulkDeleteView(generic.BulkDeleteView):
 
 class RoleListView(generic.ObjectListView):
     queryset = Role.objects.annotate(
-        prefix_count=get_subquery(Prefix, 'role'),
-        vlan_count=get_subquery(VLAN, 'role')
+        prefix_count=count_related(Prefix, 'role'),
+        vlan_count=count_related(VLAN, 'role')
     )
     table = tables.RoleTable
 
@@ -633,7 +633,7 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView):
 
 class VLANGroupListView(generic.ObjectListView):
     queryset = VLANGroup.objects.prefetch_related('site').annotate(
-        vlan_count=get_subquery(VLAN, 'group')
+        vlan_count=count_related(VLAN, 'group')
     )
     filterset = filters.VLANGroupFilterSet
     filterset_form = forms.VLANGroupFilterForm
@@ -657,7 +657,7 @@ class VLANGroupBulkImportView(generic.BulkImportView):
 
 class VLANGroupBulkDeleteView(generic.BulkDeleteView):
     queryset = VLANGroup.objects.prefetch_related('site').annotate(
-        vlan_count=get_subquery(VLAN, 'group')
+        vlan_count=count_related(VLAN, 'group')
     )
     filterset = filters.VLANGroupFilterSet
     table = tables.VLANGroupTable

+ 6 - 6
netbox/netbox/constants.py

@@ -23,7 +23,7 @@ from secrets.tables import SecretTable
 from tenancy.filters import TenantFilterSet
 from tenancy.models import Tenant
 from tenancy.tables import TenantTable
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from virtualization.filters import ClusterFilterSet, VirtualMachineFilterSet
 from virtualization.models import Cluster, VirtualMachine
 from virtualization.tables import ClusterTable, VirtualMachineDetailTable
@@ -33,7 +33,7 @@ SEARCH_TYPES = OrderedDict((
     # Circuits
     ('provider', {
         'queryset': Provider.objects.annotate(
-            count_circuits=get_subquery(Circuit, 'provider')
+            count_circuits=count_related(Circuit, 'provider')
         ),
         'filterset': ProviderFilterSet,
         'table': ProviderTable,
@@ -74,7 +74,7 @@ SEARCH_TYPES = OrderedDict((
     }),
     ('devicetype', {
         'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(
-            instance_count=get_subquery(Device, 'device_type')
+            instance_count=count_related(Device, 'device_type')
         ),
         'filterset': DeviceTypeFilterSet,
         'table': DeviceTypeTable,
@@ -90,7 +90,7 @@ SEARCH_TYPES = OrderedDict((
     }),
     ('virtualchassis', {
         'queryset': VirtualChassis.objects.prefetch_related('master').annotate(
-            member_count=get_subquery(Device, 'virtual_chassis')
+            member_count=count_related(Device, 'virtual_chassis')
         ),
         'filterset': VirtualChassisFilterSet,
         'table': VirtualChassisTable,
@@ -111,8 +111,8 @@ SEARCH_TYPES = OrderedDict((
     # Virtualization
     ('cluster', {
         'queryset': Cluster.objects.prefetch_related('type', 'group').annotate(
-            device_count=get_subquery(Device, 'cluster'),
-            vm_count=get_subquery(VirtualMachine, 'cluster')
+            device_count=count_related(Device, 'cluster'),
+            vm_count=count_related(VirtualMachine, 'cluster')
         ),
         'filterset': ClusterFilterSet,
         'table': ClusterTable,

+ 2 - 2
netbox/secrets/api/views.py

@@ -12,7 +12,7 @@ from netbox.api.views import ModelViewSet
 from secrets import filters
 from secrets.exceptions import InvalidKey
 from secrets.models import Secret, SecretRole, SessionKey, UserKey
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import serializers
 
 ERR_USERKEY_MISSING = "No UserKey found for the current user."
@@ -35,7 +35,7 @@ class SecretsRootView(APIRootView):
 
 class SecretRoleViewSet(ModelViewSet):
     queryset = SecretRole.objects.annotate(
-        secret_count=get_subquery(Secret, 'role')
+        secret_count=count_related(Secret, 'role')
     )
     serializer_class = serializers.SecretRoleSerializer
     filterset_class = filters.SecretRoleFilterSet

+ 3 - 3
netbox/secrets/views.py

@@ -7,7 +7,7 @@ from django.utils.html import escape
 from django.utils.safestring import mark_safe
 
 from netbox.views import generic
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import filters, forms, tables
 from .models import SecretRole, Secret, SessionKey, UserKey
 
@@ -28,7 +28,7 @@ def get_session_key(request):
 
 class SecretRoleListView(generic.ObjectListView):
     queryset = SecretRole.objects.annotate(
-        secret_count=get_subquery(Secret, 'role')
+        secret_count=count_related(Secret, 'role')
     )
     table = tables.SecretRoleTable
 
@@ -50,7 +50,7 @@ class SecretRoleBulkImportView(generic.BulkImportView):
 
 class SecretRoleBulkDeleteView(generic.BulkDeleteView):
     queryset = SecretRole.objects.annotate(
-        secret_count=get_subquery(Secret, 'role')
+        secret_count=count_related(Secret, 'role')
     )
     table = tables.SecretRoleTable
 

+ 10 - 10
netbox/tenancy/api/views.py

@@ -7,7 +7,7 @@ from ipam.models import IPAddress, Prefix, VLAN, VRF
 from netbox.api.views import ModelViewSet
 from tenancy import filters
 from tenancy.models import Tenant, TenantGroup
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from virtualization.models import VirtualMachine
 from . import serializers
 
@@ -44,15 +44,15 @@ class TenantViewSet(CustomFieldModelViewSet):
     queryset = Tenant.objects.prefetch_related(
         'group', 'tags'
     ).annotate(
-        circuit_count=get_subquery(Circuit, 'tenant'),
-        device_count=get_subquery(Device, 'tenant'),
-        ipaddress_count=get_subquery(IPAddress, 'tenant'),
-        prefix_count=get_subquery(Prefix, 'tenant'),
-        rack_count=get_subquery(Rack, 'tenant'),
-        site_count=get_subquery(Site, 'tenant'),
-        virtualmachine_count=get_subquery(VirtualMachine, 'tenant'),
-        vlan_count=get_subquery(VLAN, 'tenant'),
-        vrf_count=get_subquery(VRF, 'tenant')
+        circuit_count=count_related(Circuit, 'tenant'),
+        device_count=count_related(Device, 'tenant'),
+        ipaddress_count=count_related(IPAddress, 'tenant'),
+        prefix_count=count_related(Prefix, 'tenant'),
+        rack_count=count_related(Rack, 'tenant'),
+        site_count=count_related(Site, 'tenant'),
+        virtualmachine_count=count_related(VirtualMachine, 'tenant'),
+        vlan_count=count_related(VLAN, 'tenant'),
+        vrf_count=count_related(VRF, 'tenant')
     )
     serializer_class = serializers.TenantSerializer
     filterset_class = filters.TenantFilterSet

+ 1 - 1
netbox/utilities/utils.py

@@ -66,7 +66,7 @@ def dynamic_import(name):
     return mod
 
 
-def get_subquery(model, field):
+def count_related(model, field):
     """
     Return a Subquery suitable for annotating a child object count.
     """

+ 5 - 5
netbox/virtualization/api/views.py

@@ -2,7 +2,7 @@ from rest_framework.routers import APIRootView
 
 from dcim.models import Device
 from extras.api.views import ConfigContextQuerySetMixin, CustomFieldModelViewSet, ModelViewSet
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from virtualization import filters
 from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
 from . import serializers
@@ -22,7 +22,7 @@ class VirtualizationRootView(APIRootView):
 
 class ClusterTypeViewSet(ModelViewSet):
     queryset = ClusterType.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'type')
+        cluster_count=count_related(Cluster, 'type')
     )
     serializer_class = serializers.ClusterTypeSerializer
     filterset_class = filters.ClusterTypeFilterSet
@@ -30,7 +30,7 @@ class ClusterTypeViewSet(ModelViewSet):
 
 class ClusterGroupViewSet(ModelViewSet):
     queryset = ClusterGroup.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'group')
+        cluster_count=count_related(Cluster, 'group')
     )
     serializer_class = serializers.ClusterGroupSerializer
     filterset_class = filters.ClusterGroupFilterSet
@@ -40,8 +40,8 @@ class ClusterViewSet(CustomFieldModelViewSet):
     queryset = Cluster.objects.prefetch_related(
         'type', 'group', 'tenant', 'site', 'tags'
     ).annotate(
-        device_count=get_subquery(Device, 'cluster'),
-        virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
+        device_count=count_related(Device, 'cluster'),
+        virtualmachine_count=count_related(VirtualMachine, 'cluster')
     )
     serializer_class = serializers.ClusterSerializer
     filterset_class = filters.ClusterFilterSet

+ 7 - 7
netbox/virtualization/views.py

@@ -11,7 +11,7 @@ from ipam.models import IPAddress, Service
 from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
 from netbox.views import generic
 from secrets.models import Secret
-from utilities.utils import get_subquery
+from utilities.utils import count_related
 from . import filters, forms, tables
 from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
 
@@ -22,7 +22,7 @@ from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterf
 
 class ClusterTypeListView(generic.ObjectListView):
     queryset = ClusterType.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'type')
+        cluster_count=count_related(Cluster, 'type')
     )
     table = tables.ClusterTypeTable
 
@@ -44,7 +44,7 @@ class ClusterTypeBulkImportView(generic.BulkImportView):
 
 class ClusterTypeBulkDeleteView(generic.BulkDeleteView):
     queryset = ClusterType.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'type')
+        cluster_count=count_related(Cluster, 'type')
     )
     table = tables.ClusterTypeTable
 
@@ -55,7 +55,7 @@ class ClusterTypeBulkDeleteView(generic.BulkDeleteView):
 
 class ClusterGroupListView(generic.ObjectListView):
     queryset = ClusterGroup.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'group')
+        cluster_count=count_related(Cluster, 'group')
     )
     table = tables.ClusterGroupTable
 
@@ -77,7 +77,7 @@ class ClusterGroupBulkImportView(generic.BulkImportView):
 
 class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
     queryset = ClusterGroup.objects.annotate(
-        cluster_count=get_subquery(Cluster, 'group')
+        cluster_count=count_related(Cluster, 'group')
     )
     table = tables.ClusterGroupTable
 
@@ -89,8 +89,8 @@ class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
 class ClusterListView(generic.ObjectListView):
     permission_required = 'virtualization.view_cluster'
     queryset = Cluster.objects.annotate(
-        device_count=get_subquery(Device, 'cluster'),
-        vm_count=get_subquery(VirtualMachine, 'cluster')
+        device_count=count_related(Device, 'cluster'),
+        vm_count=count_related(VirtualMachine, 'cluster')
     )
     table = tables.ClusterTable
     filterset = filters.ClusterFilterSet