From 0f679e1f0374ddc14e2aa3ce4c4689233472be37 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 20 Jul 2020 12:07:19 -0400 Subject: [PATCH] Closes #4871: Specify ordering for querysets using annotate() to count related objects --- netbox/circuits/api/views.py | 4 +-- netbox/circuits/views.py | 10 +++---- netbox/dcim/api/views.py | 36 +++++++++++++--------- netbox/dcim/views.py | 48 ++++++++++++++++++++++-------- netbox/ipam/api/views.py | 10 +++---- netbox/ipam/views.py | 14 +++++---- netbox/netbox/views.py | 16 +++++++--- netbox/secrets/api/views.py | 2 +- netbox/secrets/views.py | 4 +-- netbox/tenancy/api/views.py | 8 +++-- netbox/tenancy/views.py | 8 ++++- netbox/virtualization/api/views.py | 6 ++-- netbox/virtualization/views.py | 8 ++--- 13 files changed, 113 insertions(+), 61 deletions(-) diff --git a/netbox/circuits/api/views.py b/netbox/circuits/api/views.py index 1575a181b..79c4452d2 100644 --- a/netbox/circuits/api/views.py +++ b/netbox/circuits/api/views.py @@ -19,7 +19,7 @@ from . import serializers class ProviderViewSet(CustomFieldModelViewSet): queryset = Provider.objects.prefetch_related('tags').annotate( circuit_count=Count('circuits') - ) + ).order_by(*Provider._meta.ordering) serializer_class = serializers.ProviderSerializer filterset_class = filters.ProviderFilterSet @@ -41,7 +41,7 @@ class ProviderViewSet(CustomFieldModelViewSet): class CircuitTypeViewSet(ModelViewSet): queryset = CircuitType.objects.annotate( circuit_count=Count('circuits') - ) + ).order_by(*CircuitType._meta.ordering) serializer_class = serializers.CircuitTypeSerializer filterset_class = filters.CircuitTypeFilterSet diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 55ff70327..df90a3671 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -21,7 +21,7 @@ from .models import Circuit, CircuitTermination, CircuitType, Provider # class ProviderListView(ObjectListView): - queryset = Provider.objects.annotate(count_circuits=Count('circuits')) + queryset = Provider.objects.annotate(count_circuits=Count('circuits')).order_by(*Provider._meta.ordering) filterset = filters.ProviderFilterSet filterset_form = forms.ProviderFilterForm table = tables.ProviderTable @@ -73,14 +73,14 @@ class ProviderBulkImportView(BulkImportView): class ProviderBulkEditView(BulkEditView): - queryset = Provider.objects.annotate(count_circuits=Count('circuits')) + queryset = Provider.objects.annotate(count_circuits=Count('circuits')).order_by(*Provider._meta.ordering) filterset = filters.ProviderFilterSet table = tables.ProviderTable form = forms.ProviderBulkEditForm class ProviderBulkDeleteView(BulkDeleteView): - queryset = Provider.objects.annotate(count_circuits=Count('circuits')) + queryset = Provider.objects.annotate(count_circuits=Count('circuits')).order_by(*Provider._meta.ordering) filterset = filters.ProviderFilterSet table = tables.ProviderTable @@ -90,7 +90,7 @@ class ProviderBulkDeleteView(BulkDeleteView): # class CircuitTypeListView(ObjectListView): - queryset = CircuitType.objects.annotate(circuit_count=Count('circuits')) + queryset = CircuitType.objects.annotate(circuit_count=Count('circuits')).order_by(*CircuitType._meta.ordering) table = tables.CircuitTypeTable @@ -110,7 +110,7 @@ class CircuitTypeBulkImportView(BulkImportView): class CircuitTypeBulkDeleteView(BulkDeleteView): - queryset = CircuitType.objects.annotate(circuit_count=Count('circuits')) + queryset = CircuitType.objects.annotate(circuit_count=Count('circuits')).order_by(*CircuitType._meta.ordering) table = tables.CircuitTypeTable diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index fdd58ef12..b5d68cebe 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -74,8 +74,12 @@ class CableTraceMixin(object): # class RegionViewSet(ModelViewSet): - queryset = Region.objects.annotate( - site_count=Count('sites') + queryset = Region.objects.add_related_count( + Region.objects.all(), + Site, + 'region', + 'site_count', + cumulative=True ) serializer_class = serializers.RegionSerializer filterset_class = filters.RegionFilterSet @@ -95,7 +99,7 @@ class SiteViewSet(CustomFieldModelViewSet): vlan_count=get_subquery(VLAN, 'site'), circuit_count=get_subquery(Circuit, 'terminations__site'), virtualmachine_count=get_subquery(VirtualMachine, 'cluster__site'), - ) + ).order_by(*Site._meta.ordering) serializer_class = serializers.SiteSerializer filterset_class = filters.SiteFilterSet @@ -115,9 +119,13 @@ class SiteViewSet(CustomFieldModelViewSet): # class RackGroupViewSet(ModelViewSet): - queryset = RackGroup.objects.prefetch_related('site').annotate( - rack_count=Count('racks') - ) + queryset = RackGroup.objects.add_related_count( + RackGroup.objects.all(), + Rack, + 'group', + 'rack_count', + cumulative=True + ).prefetch_related('site') serializer_class = serializers.RackGroupSerializer filterset_class = filters.RackGroupFilterSet @@ -129,7 +137,7 @@ class RackGroupViewSet(ModelViewSet): class RackRoleViewSet(ModelViewSet): queryset = RackRole.objects.annotate( rack_count=Count('racks') - ) + ).order_by(*RackRole._meta.ordering) serializer_class = serializers.RackRoleSerializer filterset_class = filters.RackRoleFilterSet @@ -144,7 +152,7 @@ class RackViewSet(CustomFieldModelViewSet): ).annotate( device_count=get_subquery(Device, 'rack'), powerfeed_count=get_subquery(PowerFeed, 'rack') - ) + ).order_by(*Rack._meta.ordering) serializer_class = serializers.RackSerializer filterset_class = filters.RackFilterSet @@ -217,7 +225,7 @@ class ManufacturerViewSet(ModelViewSet): devicetype_count=get_subquery(DeviceType, 'manufacturer'), inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'), platform_count=get_subquery(Platform, 'manufacturer') - ) + ).order_by(*Manufacturer._meta.ordering) serializer_class = serializers.ManufacturerSerializer filterset_class = filters.ManufacturerFilterSet @@ -229,7 +237,7 @@ class ManufacturerViewSet(ModelViewSet): class DeviceTypeViewSet(CustomFieldModelViewSet): queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate( device_count=Count('instances') - ) + ).order_by(*DeviceType._meta.ordering) serializer_class = serializers.DeviceTypeSerializer filterset_class = filters.DeviceTypeFilterSet @@ -294,7 +302,7 @@ class DeviceRoleViewSet(ModelViewSet): queryset = DeviceRole.objects.annotate( device_count=get_subquery(Device, 'device_role'), virtualmachine_count=get_subquery(VirtualMachine, 'role') - ) + ).order_by(*DeviceRole._meta.ordering) serializer_class = serializers.DeviceRoleSerializer filterset_class = filters.DeviceRoleFilterSet @@ -307,7 +315,7 @@ class PlatformViewSet(ModelViewSet): queryset = Platform.objects.annotate( device_count=get_subquery(Device, 'platform'), virtualmachine_count=get_subquery(VirtualMachine, 'platform') - ) + ).order_by(*Platform._meta.ordering) serializer_class = serializers.PlatformSerializer filterset_class = filters.PlatformFilterSet @@ -583,7 +591,7 @@ class CableViewSet(ModelViewSet): class VirtualChassisViewSet(ModelViewSet): queryset = VirtualChassis.objects.prefetch_related('tags').annotate( member_count=Count('members') - ) + ).order_by(*VirtualChassis._meta.ordering) serializer_class = serializers.VirtualChassisSerializer filterset_class = filters.VirtualChassisFilterSet @@ -597,7 +605,7 @@ class PowerPanelViewSet(ModelViewSet): 'site', 'rack_group' ).annotate( powerfeed_count=Count('powerfeeds') - ) + ).order_by(*PowerPanel._meta.ordering) serializer_class = serializers.PowerPanelSerializer filterset_class = filters.PowerPanelFilterSet diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 889b4d94e..2216bafd3 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -133,7 +133,13 @@ class RegionBulkImportView(BulkImportView): class RegionBulkDeleteView(BulkDeleteView): - queryset = Region.objects.all() + queryset = Region.objects.add_related_count( + Region.objects.all(), + Site, + 'region', + 'site_count', + cumulative=True + ) filterset = filters.RegionFilterSet table = tables.RegionTable @@ -238,7 +244,13 @@ class RackGroupBulkImportView(BulkImportView): class RackGroupBulkDeleteView(BulkDeleteView): - queryset = RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks')) + queryset = RackGroup.objects.add_related_count( + RackGroup.objects.all(), + Rack, + 'group', + 'rack_count', + cumulative=True + ).prefetch_related('site') filterset = filters.RackGroupFilterSet table = tables.RackGroupTable @@ -248,7 +260,7 @@ class RackGroupBulkDeleteView(BulkDeleteView): # class RackRoleListView(ObjectListView): - queryset = RackRole.objects.annotate(rack_count=Count('racks')) + queryset = RackRole.objects.annotate(rack_count=Count('racks')).order_by(*RackRole._meta.ordering) table = tables.RackRoleTable @@ -268,7 +280,7 @@ class RackRoleBulkImportView(BulkImportView): class RackRoleBulkDeleteView(BulkDeleteView): - queryset = RackRole.objects.annotate(rack_count=Count('racks')) + queryset = RackRole.objects.annotate(rack_count=Count('racks')).order_by(*RackRole._meta.ordering) table = tables.RackRoleTable @@ -281,7 +293,7 @@ class RackListView(ObjectListView): 'site', 'group', 'tenant', 'role', 'devices__device_type' ).annotate( device_count=Count('devices') - ) + ).order_by(*Rack._meta.ordering) filterset = filters.RackFilterSet filterset_form = forms.RackFilterForm table = tables.RackDetailTable @@ -465,7 +477,7 @@ class ManufacturerListView(ObjectListView): devicetype_count=Count('device_types', distinct=True), inventoryitem_count=Count('inventory_items', distinct=True), platform_count=Count('platforms', distinct=True), - ) + ).order_by(*Manufacturer._meta.ordering) table = tables.ManufacturerTable @@ -485,7 +497,9 @@ class ManufacturerBulkImportView(BulkImportView): class ManufacturerBulkDeleteView(BulkDeleteView): - queryset = Manufacturer.objects.annotate(devicetype_count=Count('device_types')) + queryset = Manufacturer.objects.annotate( + devicetype_count=Count('device_types') + ).order_by(*Manufacturer._meta.ordering) table = tables.ManufacturerTable @@ -494,7 +508,9 @@ class ManufacturerBulkDeleteView(BulkDeleteView): # class DeviceTypeListView(ObjectListView): - queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')) + queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( + instance_count=Count('instances') + ).order_by(*DeviceType._meta.ordering) filterset = filters.DeviceTypeFilterSet filterset_form = forms.DeviceTypeFilterForm table = tables.DeviceTypeTable @@ -602,14 +618,18 @@ class DeviceTypeImportView(ObjectImportView): class DeviceTypeBulkEditView(BulkEditView): - queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')) + queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( + instance_count=Count('instances') + ).order_by(*DeviceType._meta.ordering) filterset = filters.DeviceTypeFilterSet table = tables.DeviceTypeTable form = forms.DeviceTypeBulkEditForm class DeviceTypeBulkDeleteView(BulkDeleteView): - queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')) + queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( + instance_count=Count('instances') + ).order_by(*DeviceType._meta.ordering) filterset = filters.DeviceTypeFilterSet table = tables.DeviceTypeTable @@ -2152,7 +2172,9 @@ class InterfaceConnectionsListView(ObjectListView): # class VirtualChassisListView(ObjectListView): - queryset = VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')) + queryset = VirtualChassis.objects.prefetch_related('master').annotate( + member_count=Count('members') + ).order_by(*VirtualChassis._meta.ordering) table = tables.VirtualChassisTable filterset = filters.VirtualChassisFilterSet filterset_form = forms.VirtualChassisFilterForm @@ -2385,7 +2407,7 @@ class PowerPanelListView(ObjectListView): 'site', 'rack_group' ).annotate( powerfeed_count=Count('powerfeeds') - ) + ).order_by(*PowerPanel._meta.ordering) filterset = filters.PowerPanelFilterSet filterset_form = forms.PowerPanelFilterForm table = tables.PowerPanelTable @@ -2437,7 +2459,7 @@ class PowerPanelBulkDeleteView(BulkDeleteView): 'site', 'rack_group' ).annotate( rack_count=Count('powerfeeds') - ) + ).order_by(*PowerPanel._meta.ordering) filterset = filters.PowerPanelFilterSet table = tables.PowerPanelTable diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 77ac36683..80b29a76e 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -24,7 +24,7 @@ class VRFViewSet(CustomFieldModelViewSet): queryset = VRF.objects.prefetch_related('tenant').prefetch_related('tags').annotate( ipaddress_count=get_subquery(IPAddress, 'vrf'), prefix_count=get_subquery(Prefix, 'vrf') - ) + ).order_by(*VRF._meta.ordering) serializer_class = serializers.VRFSerializer filterset_class = filters.VRFFilterSet @@ -36,7 +36,7 @@ class VRFViewSet(CustomFieldModelViewSet): class RIRViewSet(ModelViewSet): queryset = RIR.objects.annotate( aggregate_count=Count('aggregates') - ) + ).order_by(*RIR._meta.ordering) serializer_class = serializers.RIRSerializer filterset_class = filters.RIRFilterSet @@ -59,7 +59,7 @@ class RoleViewSet(ModelViewSet): queryset = Role.objects.annotate( prefix_count=get_subquery(Prefix, 'role'), vlan_count=get_subquery(VLAN, 'role') - ) + ).order_by(*Role._meta.ordering) serializer_class = serializers.RoleSerializer filterset_class = filters.RoleFilterSet @@ -246,7 +246,7 @@ class IPAddressViewSet(CustomFieldModelViewSet): class VLANGroupViewSet(ModelViewSet): queryset = VLANGroup.objects.prefetch_related('site').annotate( vlan_count=Count('vlans') - ) + ).order_by(*VLANGroup._meta.ordering) serializer_class = serializers.VLANGroupSerializer filterset_class = filters.VLANGroupFilterSet @@ -260,7 +260,7 @@ class VLANViewSet(CustomFieldModelViewSet): 'site', 'group', 'tenant', 'role', 'tags' ).annotate( prefix_count=get_subquery(Prefix, 'vlan') - ) + ).order_by(*VLAN._meta.ordering) serializer_class = serializers.VLANSerializer filterset_class = filters.VLANFilterSet diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 8a9c647f0..2a4188df4 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -78,7 +78,7 @@ class VRFBulkDeleteView(BulkDeleteView): # class RIRListView(ObjectListView): - queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')) + queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')).order_by(*RIR._meta.ordering) filterset = filters.RIRFilterSet filterset_form = forms.RIRFilterForm table = tables.RIRDetailTable @@ -171,7 +171,7 @@ class RIRBulkImportView(BulkImportView): class RIRBulkDeleteView(BulkDeleteView): - queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')) + queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')).order_by(*RIR._meta.ordering) filterset = filters.RIRFilterSet table = tables.RIRTable @@ -183,7 +183,7 @@ class RIRBulkDeleteView(BulkDeleteView): class AggregateListView(ObjectListView): queryset = Aggregate.objects.prefetch_related('rir').annotate( child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) - ) + ).order_by(*Aggregate._meta.ordering) filterset = filters.AggregateFilterSet filterset_form = forms.AggregateFilterForm table = tables.AggregateDetailTable @@ -650,7 +650,9 @@ class IPAddressBulkDeleteView(BulkDeleteView): # class VLANGroupListView(ObjectListView): - queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans')) + queryset = VLANGroup.objects.prefetch_related('site').annotate( + vlan_count=Count('vlans') + ).order_by(*VLANGroup._meta.ordering) filterset = filters.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm table = tables.VLANGroupTable @@ -672,7 +674,9 @@ class VLANGroupBulkImportView(BulkImportView): class VLANGroupBulkDeleteView(BulkDeleteView): - queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans')) + queryset = VLANGroup.objects.prefetch_related('site').annotate( + vlan_count=Count('vlans') + ).order_by(*VLANGroup._meta.ordering) filterset = filters.VLANGroupFilterSet table = tables.VLANGroupTable diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py index 548173a32..a743947fe 100644 --- a/netbox/netbox/views.py +++ b/netbox/netbox/views.py @@ -46,7 +46,9 @@ SEARCH_MAX_RESULTS = 15 SEARCH_TYPES = OrderedDict(( # Circuits ('provider', { - 'queryset': Provider.objects.annotate(count_circuits=Count('circuits')), + 'queryset': Provider.objects.annotate( + count_circuits=Count('circuits') + ).order_by(*Provider._meta.ordering), 'filterset': ProviderFilterSet, 'table': ProviderTable, 'url': 'circuits:provider_list', @@ -73,13 +75,17 @@ SEARCH_TYPES = OrderedDict(( 'url': 'dcim:rack_list', }), ('rackgroup', { - 'queryset': RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks')), + 'queryset': RackGroup.objects.prefetch_related('site').annotate( + rack_count=Count('racks') + ).order_by(*RackGroup._meta.ordering), 'filterset': RackGroupFilterSet, 'table': RackGroupTable, 'url': 'dcim:rackgroup_list', }), ('devicetype', { - 'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')), + 'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate( + instance_count=Count('instances') + ).order_by(*DeviceType._meta.ordering), 'filterset': DeviceTypeFilterSet, 'table': DeviceTypeTable, 'url': 'dcim:devicetype_list', @@ -93,7 +99,9 @@ SEARCH_TYPES = OrderedDict(( 'url': 'dcim:device_list', }), ('virtualchassis', { - 'queryset': VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')), + 'queryset': VirtualChassis.objects.prefetch_related('master').annotate( + member_count=Count('members') + ).order_by(*VirtualChassis._meta.ordering), 'filterset': VirtualChassisFilterSet, 'table': VirtualChassisTable, 'url': 'dcim:virtualchassis_list', diff --git a/netbox/secrets/api/views.py b/netbox/secrets/api/views.py index 9e330b782..3ad87a8ff 100644 --- a/netbox/secrets/api/views.py +++ b/netbox/secrets/api/views.py @@ -27,7 +27,7 @@ ERR_PRIVKEY_INVALID = "Invalid private key." class SecretRoleViewSet(ModelViewSet): queryset = SecretRole.objects.annotate( secret_count=Count('secrets') - ) + ).order_by(*SecretRole._meta.ordering) serializer_class = serializers.SecretRoleSerializer filterset_class = filters.SecretRoleFilterSet diff --git a/netbox/secrets/views.py b/netbox/secrets/views.py index e9ea1835f..2872616b8 100644 --- a/netbox/secrets/views.py +++ b/netbox/secrets/views.py @@ -29,7 +29,7 @@ def get_session_key(request): # class SecretRoleListView(ObjectListView): - queryset = SecretRole.objects.annotate(secret_count=Count('secrets')) + queryset = SecretRole.objects.annotate(secret_count=Count('secrets')).order_by(*SecretRole._meta.ordering) table = tables.SecretRoleTable @@ -49,7 +49,7 @@ class SecretRoleBulkImportView(BulkImportView): class SecretRoleBulkDeleteView(BulkDeleteView): - queryset = SecretRole.objects.annotate(secret_count=Count('secrets')) + queryset = SecretRole.objects.annotate(secret_count=Count('secrets')).order_by(*SecretRole._meta.ordering) table = tables.SecretRoleTable diff --git a/netbox/tenancy/api/views.py b/netbox/tenancy/api/views.py index 148058a33..652544b21 100644 --- a/netbox/tenancy/api/views.py +++ b/netbox/tenancy/api/views.py @@ -15,8 +15,12 @@ from . import serializers # class TenantGroupViewSet(ModelViewSet): - queryset = TenantGroup.objects.annotate( - tenant_count=get_subquery(Tenant, 'group') + queryset = TenantGroup.objects.add_related_count( + TenantGroup.objects.all(), + Tenant, + 'group', + 'tenant_count', + cumulative=True ) serializer_class = serializers.TenantGroupSerializer filterset_class = filters.TenantGroupFilterSet diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index 9ef44206c..b129177eb 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -43,7 +43,13 @@ class TenantGroupBulkImportView(BulkImportView): class TenantGroupBulkDeleteView(BulkDeleteView): - queryset = TenantGroup.objects.annotate(tenant_count=Count('tenants')) + queryset = TenantGroup.objects.add_related_count( + TenantGroup.objects.all(), + Tenant, + 'group', + 'tenant_count', + cumulative=True + ) table = tables.TenantGroupTable diff --git a/netbox/virtualization/api/views.py b/netbox/virtualization/api/views.py index 867413357..df48e92e6 100644 --- a/netbox/virtualization/api/views.py +++ b/netbox/virtualization/api/views.py @@ -22,7 +22,7 @@ from . import serializers class ClusterTypeViewSet(ModelViewSet): queryset = ClusterType.objects.annotate( cluster_count=Count('clusters') - ) + ).order_by(*ClusterType._meta.ordering) serializer_class = serializers.ClusterTypeSerializer filterset_class = filters.ClusterTypeFilterSet @@ -30,7 +30,7 @@ class ClusterTypeViewSet(ModelViewSet): class ClusterGroupViewSet(ModelViewSet): queryset = ClusterGroup.objects.annotate( cluster_count=Count('clusters') - ) + ).order_by(*ClusterGroup._meta.ordering) serializer_class = serializers.ClusterGroupSerializer filterset_class = filters.ClusterGroupFilterSet @@ -41,7 +41,7 @@ class ClusterViewSet(CustomFieldModelViewSet): ).annotate( device_count=get_subquery(Device, 'cluster'), virtualmachine_count=get_subquery(VirtualMachine, 'cluster') - ) + ).order_by(*Cluster._meta.ordering) serializer_class = serializers.ClusterSerializer filterset_class = filters.ClusterFilterSet diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index 176c89f2e..a622265fc 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -22,7 +22,7 @@ from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterf # class ClusterTypeListView(ObjectListView): - queryset = ClusterType.objects.annotate(cluster_count=Count('clusters')) + queryset = ClusterType.objects.annotate(cluster_count=Count('clusters')).order_by(*ClusterType._meta.ordering) table = tables.ClusterTypeTable @@ -42,7 +42,7 @@ class ClusterTypeBulkImportView(BulkImportView): class ClusterTypeBulkDeleteView(BulkDeleteView): - queryset = ClusterType.objects.annotate(cluster_count=Count('clusters')) + queryset = ClusterType.objects.annotate(cluster_count=Count('clusters')).order_by(*ClusterType._meta.ordering) table = tables.ClusterTypeTable @@ -51,7 +51,7 @@ class ClusterTypeBulkDeleteView(BulkDeleteView): # class ClusterGroupListView(ObjectListView): - queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters')) + queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters')).order_by(*ClusterGroup._meta.ordering) table = tables.ClusterGroupTable @@ -71,7 +71,7 @@ class ClusterGroupBulkImportView(BulkImportView): class ClusterGroupBulkDeleteView(BulkDeleteView): - queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters')) + queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters')).order_by(*ClusterGroup._meta.ordering) table = tables.ClusterGroupTable