1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes: #5450 - Added Coalesce to viewsets for the _count functions

This commit is contained in:
Daniel Sheppard
2020-12-15 12:50:28 -06:00
committed by GitHub
parent 67f9e16905
commit 3c2b2f26b9
8 changed files with 49 additions and 41 deletions

View File

@ -4,6 +4,7 @@
### Bug Fixes ### Bug Fixes
* [#5450](https://github.com/netbox-community/netbox/issues/5450) - API serializer foreign count fields do not have a default value
* [#5453](https://github.com/netbox-community/netbox/issues/5453) - Correct change log representation when creating a cable * [#5453](https://github.com/netbox-community/netbox/issues/5453) - Correct change log representation when creating a cable
* [#5458](https://github.com/netbox-community/netbox/issues/5458) - Creating a component template throws an exception * [#5458](https://github.com/netbox-community/netbox/issues/5458) - Creating a component template throws an exception
* [#5461](https://github.com/netbox-community/netbox/issues/5461) - Rack Elevations throw reverse match exception * [#5461](https://github.com/netbox-community/netbox/issues/5461) - Rack Elevations throw reverse match exception

View File

@ -1,4 +1,5 @@
from django.db.models import Prefetch from django.db.models import Prefetch
from django.db.models.functions import Coalesce
from rest_framework.routers import APIRootView from rest_framework.routers import APIRootView
from circuits import filters from circuits import filters
@ -24,7 +25,7 @@ class CircuitsRootView(APIRootView):
class ProviderViewSet(CustomFieldModelViewSet): class ProviderViewSet(CustomFieldModelViewSet):
queryset = Provider.objects.prefetch_related('tags').annotate( queryset = Provider.objects.prefetch_related('tags').annotate(
circuit_count=get_subquery(Circuit, 'provider') circuit_count=Coalesce(get_subquery(Circuit, 'provider'), 0)
) )
serializer_class = serializers.ProviderSerializer serializer_class = serializers.ProviderSerializer
filterset_class = filters.ProviderFilterSet filterset_class = filters.ProviderFilterSet
@ -36,7 +37,7 @@ class ProviderViewSet(CustomFieldModelViewSet):
class CircuitTypeViewSet(ModelViewSet): class CircuitTypeViewSet(ModelViewSet):
queryset = CircuitType.objects.annotate( queryset = CircuitType.objects.annotate(
circuit_count=get_subquery(Circuit, 'type') circuit_count=Coalesce(get_subquery(Circuit, 'type'), 0)
) )
serializer_class = serializers.CircuitTypeSerializer serializer_class = serializers.CircuitTypeSerializer
filterset_class = filters.CircuitTypeFilterSet filterset_class = filters.CircuitTypeFilterSet

View File

@ -3,6 +3,7 @@ from collections import OrderedDict
from django.conf import settings from django.conf import settings
from django.db.models import F from django.db.models import F
from django.db.models.functions import Coalesce
from django.http import HttpResponseForbidden, HttpResponse from django.http import HttpResponseForbidden, HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from drf_yasg import openapi from drf_yasg import openapi
@ -119,12 +120,12 @@ class SiteViewSet(CustomFieldModelViewSet):
queryset = Site.objects.prefetch_related( queryset = Site.objects.prefetch_related(
'region', 'tenant', 'tags' 'region', 'tenant', 'tags'
).annotate( ).annotate(
device_count=get_subquery(Device, 'site'), device_count=Coalesce(get_subquery(Device, 'site'), 0),
rack_count=get_subquery(Rack, 'site'), rack_count=Coalesce(get_subquery(Rack, 'site'), 0),
prefix_count=get_subquery(Prefix, 'site'), prefix_count=Coalesce(get_subquery(Prefix, 'site'), 0),
vlan_count=get_subquery(VLAN, 'site'), vlan_count=Coalesce(get_subquery(VLAN, 'site'), 0),
circuit_count=get_subquery(Circuit, 'terminations__site'), circuit_count=Coalesce(get_subquery(Circuit, 'terminations__site'), 0),
virtualmachine_count=get_subquery(VirtualMachine, 'cluster__site'), virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'cluster__site'), 0),
) )
serializer_class = serializers.SiteSerializer serializer_class = serializers.SiteSerializer
filterset_class = filters.SiteFilterSet filterset_class = filters.SiteFilterSet
@ -152,7 +153,7 @@ class RackGroupViewSet(ModelViewSet):
class RackRoleViewSet(ModelViewSet): class RackRoleViewSet(ModelViewSet):
queryset = RackRole.objects.annotate( queryset = RackRole.objects.annotate(
rack_count=get_subquery(Rack, 'role') rack_count=Coalesce(get_subquery(Rack, 'role'), 0)
) )
serializer_class = serializers.RackRoleSerializer serializer_class = serializers.RackRoleSerializer
filterset_class = filters.RackRoleFilterSet filterset_class = filters.RackRoleFilterSet
@ -166,8 +167,8 @@ class RackViewSet(CustomFieldModelViewSet):
queryset = Rack.objects.prefetch_related( queryset = Rack.objects.prefetch_related(
'site', 'group__site', 'role', 'tenant', 'tags' 'site', 'group__site', 'role', 'tenant', 'tags'
).annotate( ).annotate(
device_count=get_subquery(Device, 'rack'), device_count=Coalesce(get_subquery(Device, 'rack'), 0),
powerfeed_count=get_subquery(PowerFeed, 'rack') powerfeed_count=Coalesce(get_subquery(PowerFeed, 'rack'), 0)
) )
serializer_class = serializers.RackSerializer serializer_class = serializers.RackSerializer
filterset_class = filters.RackFilterSet filterset_class = filters.RackFilterSet
@ -240,9 +241,9 @@ class RackReservationViewSet(ModelViewSet):
class ManufacturerViewSet(ModelViewSet): class ManufacturerViewSet(ModelViewSet):
queryset = Manufacturer.objects.annotate( queryset = Manufacturer.objects.annotate(
devicetype_count=get_subquery(DeviceType, 'manufacturer'), devicetype_count=Coalesce(get_subquery(DeviceType, 'manufacturer'), 0),
inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'), inventoryitem_count=Coalesce(get_subquery(InventoryItem, 'manufacturer'), 0),
platform_count=get_subquery(Platform, 'manufacturer') platform_count=Coalesce(get_subquery(Platform, 'manufacturer'), 0)
) )
serializer_class = serializers.ManufacturerSerializer serializer_class = serializers.ManufacturerSerializer
filterset_class = filters.ManufacturerFilterSet filterset_class = filters.ManufacturerFilterSet
@ -254,7 +255,7 @@ class ManufacturerViewSet(ModelViewSet):
class DeviceTypeViewSet(CustomFieldModelViewSet): class DeviceTypeViewSet(CustomFieldModelViewSet):
queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate( queryset = DeviceType.objects.prefetch_related('manufacturer', 'tags').annotate(
device_count=get_subquery(Device, 'device_type') device_count=Coalesce(get_subquery(Device, 'device_type'), 0)
) )
serializer_class = serializers.DeviceTypeSerializer serializer_class = serializers.DeviceTypeSerializer
filterset_class = filters.DeviceTypeFilterSet filterset_class = filters.DeviceTypeFilterSet
@ -318,8 +319,8 @@ class DeviceBayTemplateViewSet(ModelViewSet):
class DeviceRoleViewSet(ModelViewSet): class DeviceRoleViewSet(ModelViewSet):
queryset = DeviceRole.objects.annotate( queryset = DeviceRole.objects.annotate(
device_count=get_subquery(Device, 'device_role'), device_count=Coalesce(get_subquery(Device, 'device_role'), 0),
virtualmachine_count=get_subquery(VirtualMachine, 'role') virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'role'), 0)
) )
serializer_class = serializers.DeviceRoleSerializer serializer_class = serializers.DeviceRoleSerializer
filterset_class = filters.DeviceRoleFilterSet filterset_class = filters.DeviceRoleFilterSet
@ -331,8 +332,8 @@ class DeviceRoleViewSet(ModelViewSet):
class PlatformViewSet(ModelViewSet): class PlatformViewSet(ModelViewSet):
queryset = Platform.objects.annotate( queryset = Platform.objects.annotate(
device_count=get_subquery(Device, 'platform'), device_count=Coalesce(get_subquery(Device, 'platform'), 0),
virtualmachine_count=get_subquery(VirtualMachine, 'platform') virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'platform'), 0)
) )
serializer_class = serializers.PlatformSerializer serializer_class = serializers.PlatformSerializer
filterset_class = filters.PlatformFilterSet filterset_class = filters.PlatformFilterSet
@ -596,7 +597,7 @@ class CableViewSet(ModelViewSet):
class VirtualChassisViewSet(ModelViewSet): class VirtualChassisViewSet(ModelViewSet):
queryset = VirtualChassis.objects.prefetch_related('tags').annotate( queryset = VirtualChassis.objects.prefetch_related('tags').annotate(
member_count=get_subquery(Device, 'virtual_chassis') member_count=Coalesce(get_subquery(Device, 'virtual_chassis'), 0)
) )
serializer_class = serializers.VirtualChassisSerializer serializer_class = serializers.VirtualChassisSerializer
filterset_class = filters.VirtualChassisFilterSet filterset_class = filters.VirtualChassisFilterSet
@ -610,7 +611,7 @@ class PowerPanelViewSet(ModelViewSet):
queryset = PowerPanel.objects.prefetch_related( queryset = PowerPanel.objects.prefetch_related(
'site', 'rack_group' 'site', 'rack_group'
).annotate( ).annotate(
powerfeed_count=get_subquery(PowerFeed, 'power_panel') powerfeed_count=Coalesce(get_subquery(PowerFeed, 'power_panel'), 0)
) )
serializer_class = serializers.PowerPanelSerializer serializer_class = serializers.PowerPanelSerializer
filterset_class = filters.PowerPanelFilterSet filterset_class = filters.PowerPanelFilterSet

View File

@ -1,4 +1,5 @@
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models.functions import Coalesce
from django.http import Http404 from django.http import Http404
from django_rq.queues import get_connection from django_rq.queues import get_connection
from rest_framework import status from rest_framework import status
@ -102,7 +103,7 @@ class ExportTemplateViewSet(ModelViewSet):
class TagViewSet(ModelViewSet): class TagViewSet(ModelViewSet):
queryset = Tag.objects.annotate( queryset = Tag.objects.annotate(
tagged_items=get_subquery(TaggedItem, 'tag') tagged_items=Coalesce(get_subquery(TaggedItem, 'tag'), 0)
) )
serializer_class = serializers.TagSerializer serializer_class = serializers.TagSerializer
filterset_class = filters.TagFilterSet filterset_class = filters.TagFilterSet

View File

@ -1,4 +1,5 @@
from django.conf import settings from django.conf import settings
from django.db.models.functions import Coalesce
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django_pglocks import advisory_lock from django_pglocks import advisory_lock
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
@ -32,8 +33,8 @@ class VRFViewSet(CustomFieldModelViewSet):
queryset = VRF.objects.prefetch_related('tenant').prefetch_related( queryset = VRF.objects.prefetch_related('tenant').prefetch_related(
'import_targets', 'export_targets', 'tags' 'import_targets', 'export_targets', 'tags'
).annotate( ).annotate(
ipaddress_count=get_subquery(IPAddress, 'vrf'), ipaddress_count=Coalesce(get_subquery(IPAddress, 'vrf'), 0),
prefix_count=get_subquery(Prefix, 'vrf') prefix_count=Coalesce(get_subquery(Prefix, 'vrf'), 0)
) )
serializer_class = serializers.VRFSerializer serializer_class = serializers.VRFSerializer
filterset_class = filters.VRFFilterSet filterset_class = filters.VRFFilterSet
@ -55,7 +56,7 @@ class RouteTargetViewSet(CustomFieldModelViewSet):
class RIRViewSet(ModelViewSet): class RIRViewSet(ModelViewSet):
queryset = RIR.objects.annotate( queryset = RIR.objects.annotate(
aggregate_count=get_subquery(Aggregate, 'rir') aggregate_count=Coalesce(get_subquery(Aggregate, 'rir'), 0)
) )
serializer_class = serializers.RIRSerializer serializer_class = serializers.RIRSerializer
filterset_class = filters.RIRFilterSet filterset_class = filters.RIRFilterSet
@ -77,8 +78,8 @@ class AggregateViewSet(CustomFieldModelViewSet):
class RoleViewSet(ModelViewSet): class RoleViewSet(ModelViewSet):
queryset = Role.objects.annotate( queryset = Role.objects.annotate(
prefix_count=get_subquery(Prefix, 'role'), prefix_count=Coalesce(get_subquery(Prefix, 'role'), 0),
vlan_count=get_subquery(VLAN, 'role') vlan_count=Coalesce(get_subquery(VLAN, 'role'), 0)
) )
serializer_class = serializers.RoleSerializer serializer_class = serializers.RoleSerializer
filterset_class = filters.RoleFilterSet filterset_class = filters.RoleFilterSet
@ -272,7 +273,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
class VLANGroupViewSet(ModelViewSet): class VLANGroupViewSet(ModelViewSet):
queryset = VLANGroup.objects.prefetch_related('site').annotate( queryset = VLANGroup.objects.prefetch_related('site').annotate(
vlan_count=get_subquery(VLAN, 'group') vlan_count=Coalesce(get_subquery(VLAN, 'group'), 0)
) )
serializer_class = serializers.VLANGroupSerializer serializer_class = serializers.VLANGroupSerializer
filterset_class = filters.VLANGroupFilterSet filterset_class = filters.VLANGroupFilterSet
@ -286,7 +287,7 @@ class VLANViewSet(CustomFieldModelViewSet):
queryset = VLAN.objects.prefetch_related( queryset = VLAN.objects.prefetch_related(
'site', 'group', 'tenant', 'role', 'tags' 'site', 'group', 'tenant', 'role', 'tags'
).annotate( ).annotate(
prefix_count=get_subquery(Prefix, 'vlan') prefix_count=Coalesce(get_subquery(Prefix, 'vlan'), 0)
) )
serializer_class = serializers.VLANSerializer serializer_class = serializers.VLANSerializer
filterset_class = filters.VLANFilterSet filterset_class = filters.VLANFilterSet

View File

@ -1,6 +1,7 @@
import base64 import base64
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from django.db.models.functions import Coalesce
from django.http import HttpResponseBadRequest from django.http import HttpResponseBadRequest
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
@ -35,7 +36,7 @@ class SecretsRootView(APIRootView):
class SecretRoleViewSet(ModelViewSet): class SecretRoleViewSet(ModelViewSet):
queryset = SecretRole.objects.annotate( queryset = SecretRole.objects.annotate(
secret_count=get_subquery(Secret, 'role') secret_count=Coalesce(get_subquery(Secret, 'role'), 0)
) )
serializer_class = serializers.SecretRoleSerializer serializer_class = serializers.SecretRoleSerializer
filterset_class = filters.SecretRoleFilterSet filterset_class = filters.SecretRoleFilterSet

View File

@ -1,3 +1,4 @@
from django.db.models.functions import Coalesce
from rest_framework.routers import APIRootView from rest_framework.routers import APIRootView
from circuits.models import Circuit from circuits.models import Circuit
@ -46,13 +47,13 @@ class TenantViewSet(CustomFieldModelViewSet):
).annotate( ).annotate(
circuit_count=get_subquery(Circuit, 'tenant'), circuit_count=get_subquery(Circuit, 'tenant'),
device_count=get_subquery(Device, 'tenant'), device_count=get_subquery(Device, 'tenant'),
ipaddress_count=get_subquery(IPAddress, 'tenant'), ipaddress_count=Coalesce(get_subquery(IPAddress, 'tenant'), 0),
prefix_count=get_subquery(Prefix, 'tenant'), prefix_count=Coalesce(get_subquery(Prefix, 'tenant'), 0),
rack_count=get_subquery(Rack, 'tenant'), rack_count=Coalesce(get_subquery(Rack, 'tenant'), 0),
site_count=get_subquery(Site, 'tenant'), site_count=Coalesce(get_subquery(Site, 'tenant'), 0),
virtualmachine_count=get_subquery(VirtualMachine, 'tenant'), virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'tenant'), 0),
vlan_count=get_subquery(VLAN, 'tenant'), vlan_count=Coalesce(get_subquery(VLAN, 'tenant'), 0),
vrf_count=get_subquery(VRF, 'tenant') vrf_count=Coalesce(get_subquery(VRF, 'tenant'), 0)
) )
serializer_class = serializers.TenantSerializer serializer_class = serializers.TenantSerializer
filterset_class = filters.TenantFilterSet filterset_class = filters.TenantFilterSet

View File

@ -1,3 +1,4 @@
from django.db.models.functions import Coalesce
from rest_framework.routers import APIRootView from rest_framework.routers import APIRootView
from dcim.models import Device from dcim.models import Device
@ -22,7 +23,7 @@ class VirtualizationRootView(APIRootView):
class ClusterTypeViewSet(ModelViewSet): class ClusterTypeViewSet(ModelViewSet):
queryset = ClusterType.objects.annotate( queryset = ClusterType.objects.annotate(
cluster_count=get_subquery(Cluster, 'type') cluster_count=Coalesce(get_subquery(Cluster, 'type'), 0)
) )
serializer_class = serializers.ClusterTypeSerializer serializer_class = serializers.ClusterTypeSerializer
filterset_class = filters.ClusterTypeFilterSet filterset_class = filters.ClusterTypeFilterSet
@ -30,7 +31,7 @@ class ClusterTypeViewSet(ModelViewSet):
class ClusterGroupViewSet(ModelViewSet): class ClusterGroupViewSet(ModelViewSet):
queryset = ClusterGroup.objects.annotate( queryset = ClusterGroup.objects.annotate(
cluster_count=get_subquery(Cluster, 'group') cluster_count=Coalesce(get_subquery(Cluster, 'group'), 0)
) )
serializer_class = serializers.ClusterGroupSerializer serializer_class = serializers.ClusterGroupSerializer
filterset_class = filters.ClusterGroupFilterSet filterset_class = filters.ClusterGroupFilterSet
@ -40,8 +41,8 @@ class ClusterViewSet(CustomFieldModelViewSet):
queryset = Cluster.objects.prefetch_related( queryset = Cluster.objects.prefetch_related(
'type', 'group', 'tenant', 'site', 'tags' 'type', 'group', 'tenant', 'site', 'tags'
).annotate( ).annotate(
device_count=get_subquery(Device, 'cluster'), device_count=Coalesce(get_subquery(Device, 'cluster'), 0),
virtualmachine_count=get_subquery(VirtualMachine, 'cluster') virtualmachine_count=Coalesce(get_subquery(VirtualMachine, 'cluster'), 0)
) )
serializer_class = serializers.ClusterSerializer serializer_class = serializers.ClusterSerializer
filterset_class = filters.ClusterFilterSet filterset_class = filters.ClusterFilterSet