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

Added '*_count' fields for child objects

Jeremy Stretch 6 лет назад
Родитель
Сommit
017a5011ec

+ 10 - 7
netbox/dcim/api/serializers.py

@@ -72,20 +72,20 @@ class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer):
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     time_zone = TimeZoneField(required=False)
     time_zone = TimeZoneField(required=False)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
+    circuit_count = serializers.IntegerField(read_only=True)
+    device_count = serializers.IntegerField(read_only=True)
     prefix_count = serializers.IntegerField(read_only=True)
     prefix_count = serializers.IntegerField(read_only=True)
-    vlan_count = serializers.IntegerField(read_only=True)
     rack_count = serializers.IntegerField(read_only=True)
     rack_count = serializers.IntegerField(read_only=True)
-    device_count = serializers.IntegerField(read_only=True)
-    circuit_count = serializers.IntegerField(read_only=True)
     virtualmachine_count = serializers.IntegerField(read_only=True)
     virtualmachine_count = serializers.IntegerField(read_only=True)
+    vlan_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = Site
         model = Site
         fields = [
         fields = [
             'id', 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description',
             'id', 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description',
             'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone',
             'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone',
-            'contact_email', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'prefix_count',
-            'vlan_count', 'rack_count', 'device_count', 'circuit_count', 'virtualmachine_count',
+            'contact_email', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count',
+            'device_count', 'prefix_count', 'rack_count', 'virtualmachine_count', 'vlan_count',
         ]
         ]
 
 
 
 
@@ -121,13 +121,14 @@ class RackSerializer(TaggitSerializer, CustomFieldModelSerializer):
     outer_unit = ChoiceField(choices=RACK_DIMENSION_UNIT_CHOICES, required=False)
     outer_unit = ChoiceField(choices=RACK_DIMENSION_UNIT_CHOICES, required=False)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
     device_count = serializers.IntegerField(read_only=True)
     device_count = serializers.IntegerField(read_only=True)
+    powerfeed_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = Rack
         model = Rack
         fields = [
         fields = [
             'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'status', 'role', 'serial',
             'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'status', 'role', 'serial',
             'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
             'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
-            'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
+            'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count',
         ]
         ]
         # Omit the UniqueTogetherValidator that would be automatically added to validate (group, facility_id). This
         # Omit the UniqueTogetherValidator that would be automatically added to validate (group, facility_id). This
         # prevents facility_id from being interpreted as a required field.
         # prevents facility_id from being interpreted as a required field.
@@ -175,10 +176,12 @@ class RackReservationSerializer(ValidatedModelSerializer):
 
 
 class ManufacturerSerializer(ValidatedModelSerializer):
 class ManufacturerSerializer(ValidatedModelSerializer):
     devicetype_count = serializers.IntegerField(read_only=True)
     devicetype_count = serializers.IntegerField(read_only=True)
+    inventoryitem_count = serializers.IntegerField(read_only=True)
+    platform_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = Manufacturer
         model = Manufacturer
-        fields = ['id', 'name', 'slug', 'devicetype_count']
+        fields = ['id', 'name', 'slug', 'devicetype_count', 'inventoryitem_count', 'platform_count']
 
 
 
 
 class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):
 class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):

+ 6 - 3
netbox/dcim/api/views.py

@@ -165,11 +165,12 @@ class RackRoleViewSet(ModelViewSet):
 
 
 class RackViewSet(CustomFieldModelViewSet):
 class RackViewSet(CustomFieldModelViewSet):
     queryset = Rack.objects.select_related(
     queryset = Rack.objects.select_related(
-        'site', 'group__site', 'tenant'
+        'site', 'group__site', 'role', 'tenant'
     ).prefetch_related(
     ).prefetch_related(
         'tags'
         'tags'
     ).annotate(
     ).annotate(
-        device_count=Count('devices')
+        device_count=get_subquery(Device, 'rack'),
+        powerfeed_count=get_subquery(PowerFeed, 'rack')
     )
     )
     serializer_class = serializers.RackSerializer
     serializer_class = serializers.RackSerializer
     filterset_class = filters.RackFilter
     filterset_class = filters.RackFilter
@@ -220,7 +221,9 @@ class RackReservationViewSet(ModelViewSet):
 
 
 class ManufacturerViewSet(ModelViewSet):
 class ManufacturerViewSet(ModelViewSet):
     queryset = Manufacturer.objects.annotate(
     queryset = Manufacturer.objects.annotate(
-        devicetype_count=Count('device_types')
+        devicetype_count=get_subquery(DeviceType, 'manufacturer'),
+        inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'),
+        platform_count=get_subquery(Platform, 'manufacturer')
     )
     )
     serializer_class = serializers.ManufacturerSerializer
     serializer_class = serializers.ManufacturerSerializer
     filterset_class = filters.ManufacturerFilter
     filterset_class = filters.ManufacturerFilter

+ 4 - 2
netbox/ipam/api/serializers.py

@@ -25,13 +25,14 @@ from .nested_serializers import *
 class VRFSerializer(TaggitSerializer, CustomFieldModelSerializer):
 class VRFSerializer(TaggitSerializer, CustomFieldModelSerializer):
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     tenant = NestedTenantSerializer(required=False, allow_null=True)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
+    ipaddress_count = serializers.IntegerField(read_only=True)
     prefix_count = serializers.IntegerField(read_only=True)
     prefix_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = VRF
         model = VRF
         fields = [
         fields = [
             'id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'tags', 'display_name', 'custom_fields',
             'id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'tags', 'display_name', 'custom_fields',
-            'created', 'last_updated', 'prefix_count',
+            'created', 'last_updated', 'ipaddress_count', 'prefix_count',
         ]
         ]
 
 
 
 
@@ -104,12 +105,13 @@ class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer):
     status = ChoiceField(choices=VLAN_STATUS_CHOICES, required=False)
     status = ChoiceField(choices=VLAN_STATUS_CHOICES, required=False)
     role = NestedRoleSerializer(required=False, allow_null=True)
     role = NestedRoleSerializer(required=False, allow_null=True)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
+    prefix_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = VLAN
         model = VLAN
         fields = [
         fields = [
             'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'tags', 'display_name',
             'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'tags', 'display_name',
-            'custom_fields', 'created', 'last_updated',
+            'custom_fields', 'created', 'last_updated', 'prefix_count',
         ]
         ]
         validators = []
         validators = []
 
 

+ 9 - 2
netbox/ipam/api/views.py

@@ -34,7 +34,8 @@ class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
 
 
 class VRFViewSet(CustomFieldModelViewSet):
 class VRFViewSet(CustomFieldModelViewSet):
     queryset = VRF.objects.select_related('tenant').prefetch_related('tags').annotate(
     queryset = VRF.objects.select_related('tenant').prefetch_related('tags').annotate(
-        prefix_count=Count('prefixes')
+        ipaddress_count=get_subquery(IPAddress, 'vrf'),
+        prefix_count=get_subquery(Prefix, 'vrf')
     )
     )
     serializer_class = serializers.VRFSerializer
     serializer_class = serializers.VRFSerializer
     filterset_class = filters.VRFFilter
     filterset_class = filters.VRFFilter
@@ -288,7 +289,13 @@ class VLANGroupViewSet(ModelViewSet):
 #
 #
 
 
 class VLANViewSet(CustomFieldModelViewSet):
 class VLANViewSet(CustomFieldModelViewSet):
-    queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('tags')
+    queryset = VLAN.objects.select_related(
+        'site', 'group', 'tenant', 'role'
+    ).prefetch_related(
+        'tags'
+    ).annotate(
+        prefix_count=get_subquery(Prefix, 'role')
+    )
     serializer_class = serializers.VLANSerializer
     serializer_class = serializers.VLANSerializer
     filterset_class = filters.VLANFilter
     filterset_class = filters.VLANFilter
 
 

+ 11 - 1
netbox/tenancy/api/serializers.py

@@ -22,10 +22,20 @@ class TenantGroupSerializer(ValidatedModelSerializer):
 class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer):
 class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer):
     group = NestedTenantGroupSerializer(required=False)
     group = NestedTenantGroupSerializer(required=False)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
+    circuit_count = serializers.IntegerField(read_only=True)
+    device_count = serializers.IntegerField(read_only=True)
+    ipaddress_count = serializers.IntegerField(read_only=True)
+    prefix_count = serializers.IntegerField(read_only=True)
+    rack_count = serializers.IntegerField(read_only=True)
+    site_count = serializers.IntegerField(read_only=True)
+    virtualmachine_count = serializers.IntegerField(read_only=True)
+    vlan_count = serializers.IntegerField(read_only=True)
+    vrf_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = Tenant
         model = Tenant
         fields = [
         fields = [
             'id', 'name', 'slug', 'group', 'description', 'comments', 'tags', 'custom_fields', 'created',
             'id', 'name', 'slug', 'group', 'description', 'comments', 'tags', 'custom_fields', 'created',
-            'last_updated',
+            'last_updated', 'circuit_count', 'device_count', 'ipaddress_count', 'prefix_count', 'rack_count',
+            'site_count', 'virtualmachine_count', 'vlan_count', 'vrf_count',
         ]
         ]

+ 21 - 4
netbox/tenancy/api/views.py

@@ -1,9 +1,12 @@
-from django.db.models import Count
-
+from circuits.models import Circuit
+from dcim.models import Device, Rack, Site
 from extras.api.views import CustomFieldModelViewSet
 from extras.api.views import CustomFieldModelViewSet
+from ipam.models import IPAddress, Prefix, VLAN, VRF
 from tenancy import filters
 from tenancy import filters
 from tenancy.models import Tenant, TenantGroup
 from tenancy.models import Tenant, TenantGroup
 from utilities.api import FieldChoicesViewSet, ModelViewSet
 from utilities.api import FieldChoicesViewSet, ModelViewSet
+from utilities.utils import get_subquery
+from virtualization.models import VirtualMachine
 from . import serializers
 from . import serializers
 
 
 
 
@@ -21,7 +24,7 @@ class TenancyFieldChoicesViewSet(FieldChoicesViewSet):
 
 
 class TenantGroupViewSet(ModelViewSet):
 class TenantGroupViewSet(ModelViewSet):
     queryset = TenantGroup.objects.annotate(
     queryset = TenantGroup.objects.annotate(
-        tenant_count=Count('tenants')
+        tenant_count=get_subquery(Tenant, 'group')
     )
     )
     serializer_class = serializers.TenantGroupSerializer
     serializer_class = serializers.TenantGroupSerializer
     filterset_class = filters.TenantGroupFilter
     filterset_class = filters.TenantGroupFilter
@@ -32,6 +35,20 @@ class TenantGroupViewSet(ModelViewSet):
 #
 #
 
 
 class TenantViewSet(CustomFieldModelViewSet):
 class TenantViewSet(CustomFieldModelViewSet):
-    queryset = Tenant.objects.select_related('group').prefetch_related('tags')
+    queryset = Tenant.objects.select_related(
+        'group'
+    ).prefetch_related(
+        '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')
+    )
     serializer_class = serializers.TenantSerializer
     serializer_class = serializers.TenantSerializer
     filterset_class = filters.TenantFilter
     filterset_class = filters.TenantFilter

+ 2 - 1
netbox/virtualization/api/serializers.py

@@ -40,13 +40,14 @@ class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer):
     group = NestedClusterGroupSerializer(required=False, allow_null=True)
     group = NestedClusterGroupSerializer(required=False, allow_null=True)
     site = NestedSiteSerializer(required=False, allow_null=True)
     site = NestedSiteSerializer(required=False, allow_null=True)
     tags = TagListSerializerField(required=False)
     tags = TagListSerializerField(required=False)
+    device_count = serializers.IntegerField(read_only=True)
     virtualmachine_count = serializers.IntegerField(read_only=True)
     virtualmachine_count = serializers.IntegerField(read_only=True)
 
 
     class Meta:
     class Meta:
         model = Cluster
         model = Cluster
         fields = [
         fields = [
             'id', 'name', 'type', 'group', 'site', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
             'id', 'name', 'type', 'group', 'site', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
-            'virtualmachine_count',
+            'device_count', 'virtualmachine_count',
         ]
         ]
 
 
 
 

+ 9 - 3
netbox/virtualization/api/views.py

@@ -1,8 +1,9 @@
 from django.db.models import Count
 from django.db.models import Count
 
 
-from dcim.models import Interface
+from dcim.models import Device, Interface
 from extras.api.views import CustomFieldModelViewSet
 from extras.api.views import CustomFieldModelViewSet
 from utilities.api import FieldChoicesViewSet, ModelViewSet
 from utilities.api import FieldChoicesViewSet, ModelViewSet
+from utilities.utils import get_subquery
 from virtualization import filters
 from virtualization import filters
 from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
 from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
 from . import serializers
 from . import serializers
@@ -39,8 +40,13 @@ class ClusterGroupViewSet(ModelViewSet):
 
 
 
 
 class ClusterViewSet(CustomFieldModelViewSet):
 class ClusterViewSet(CustomFieldModelViewSet):
-    queryset = Cluster.objects.select_related('type', 'group').prefetch_related('tags').annotate(
-        virtualmachine_count=Count('virtual_machines')
+    queryset = Cluster.objects.select_related(
+        'type', 'group', 'site',
+    ).prefetch_related(
+        'tags'
+    ).annotate(
+        device_count=get_subquery(Device, 'cluster'),
+        virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
     )
     )
     serializer_class = serializers.ClusterSerializer
     serializer_class = serializers.ClusterSerializer
     filterset_class = filters.ClusterFilter
     filterset_class = filters.ClusterFilter