Closes #4871: Specify ordering for querysets using annotate() to count related objects

This commit is contained in:
Jeremy Stretch 2020-07-20 12:07:19 -04:00
parent 39dc1f882a
commit 0f679e1f03
13 changed files with 113 additions and 61 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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',

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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