From debed6a960af90f5fb697d6ef9c902a632e1a040 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 15 Apr 2023 18:51:28 +0530 Subject: [PATCH 01/14] Update serializers.py --- netbox/ipam/api/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 6ec062aee2d..2539b342396 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -184,12 +184,13 @@ class VLANGroupSerializer(NetBoxModelSerializer): scope_id = serializers.IntegerField(allow_null=True, required=False, default=None) scope = serializers.SerializerMethodField(read_only=True) vlan_count = serializers.IntegerField(read_only=True) + utilization = serializers.CharField(source='get_utilization') class Meta: model = VLANGroup fields = [ 'id', 'url', 'display', 'name', 'slug', 'scope_type', 'scope_id', 'scope', 'min_vid', 'max_vid', - 'description', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count', + 'description', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count', 'utilization' ] validators = [] From d014cb7f7cb8db0464ccaa35f0ff64d980dc38b7 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 15 Apr 2023 18:55:49 +0530 Subject: [PATCH 02/14] Update vlans.py --- netbox/ipam/models/vlans.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index bf6c6a52eb4..7bffb3fb315 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -113,6 +113,15 @@ def get_next_available_vid(self): if available_vids: return available_vids[0] return None + + def get_utilization(self): + """ + Return the percentage of utilization for this vlan group. + """ + assigned_vlan = VLAN.objects.filter(group=self.id).count() + if assigned_vlan != 0: + return round(assigned_vlan / (self.max_vid - self.min_vid + 1) * 100, 2) + return 0.0 class VLAN(PrimaryModel): From 617b0d2e34bcba1d65c80236cb36d85330e834ad Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 15 Apr 2023 18:57:09 +0530 Subject: [PATCH 03/14] Update vlans.py --- netbox/ipam/tables/vlans.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index 6fa2cd2da48..c16de3e9cdd 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -70,6 +70,10 @@ class VLANGroupTable(NetBoxTable): url_params={'group_id': 'pk'}, verbose_name='VLANs' ) + get_utilization = columns.UtilizationColumn( + orderable=False, + verbose_name='Utilization' + ) tags = columns.TagColumn( url_name='ipam:vlangroup_list' ) @@ -81,9 +85,9 @@ class Meta(NetBoxTable.Meta): model = VLANGroup fields = ( 'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description', - 'tags', 'created', 'last_updated', 'actions', + 'tags', 'created', 'last_updated', 'actions', 'get_utilization', ) - default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description') + default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'get_utilization', 'description') # From cd97ccc23cf973e84fd103d3e6028382a1074f98 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 15 Apr 2023 18:58:41 +0530 Subject: [PATCH 04/14] Update vlangroup.html --- netbox/templates/ipam/vlangroup.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/netbox/templates/ipam/vlangroup.html b/netbox/templates/ipam/vlangroup.html index 822b4a0460e..920a208caa4 100644 --- a/netbox/templates/ipam/vlangroup.html +++ b/netbox/templates/ipam/vlangroup.html @@ -48,6 +48,10 @@
VLAN Group
{{ vlans_count }} + + Utilization + {% utilization_graph object.get_utilization %} + From 7cb990fd2d838529939507f960648539a94208e3 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sun, 16 Apr 2023 00:54:27 +0530 Subject: [PATCH 05/14] Update vlans.py --- netbox/ipam/models/vlans.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 7bffb3fb315..2a6f39ce2a0 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -113,7 +113,7 @@ def get_next_available_vid(self): if available_vids: return available_vids[0] return None - + def get_utilization(self): """ Return the percentage of utilization for this vlan group. From 50c75b5190efe43ab2b518e42cd309fdd5c0f227 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sun, 16 Apr 2023 00:54:58 +0530 Subject: [PATCH 06/14] Update vlans.py --- netbox/ipam/tables/vlans.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index c16de3e9cdd..b2d9d5c2b7f 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -71,7 +71,7 @@ class VLANGroupTable(NetBoxTable): verbose_name='VLANs' ) get_utilization = columns.UtilizationColumn( - orderable=False, + orderable=False, verbose_name='Utilization' ) tags = columns.TagColumn( From f3e8cd3ab714884a10a04c099138de564bc253ea Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sun, 16 Apr 2023 01:07:04 +0530 Subject: [PATCH 07/14] Update serializers.py --- netbox/ipam/api/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 2539b342396..6bbed976b5a 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -184,7 +184,7 @@ class VLANGroupSerializer(NetBoxModelSerializer): scope_id = serializers.IntegerField(allow_null=True, required=False, default=None) scope = serializers.SerializerMethodField(read_only=True) vlan_count = serializers.IntegerField(read_only=True) - utilization = serializers.CharField(source='get_utilization') + utilization = serializers.CharField(source='get_utilization', read_only=True) class Meta: model = VLANGroup From d6fda266d40146e2b2ba80409a39fd08c340150d Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 13 May 2023 03:23:26 +0530 Subject: [PATCH 08/14] adds db annotation to calculate utilization --- netbox/ipam/api/serializers.py | 2 +- netbox/ipam/api/views.py | 4 +++- netbox/ipam/models/vlans.py | 9 --------- netbox/ipam/tables/vlans.py | 6 +++--- netbox/ipam/views.py | 21 +++++++++++++-------- netbox/templates/ipam/vlangroup.html | 6 ++---- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index a5605751c2f..1501f16dca5 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -218,7 +218,7 @@ class VLANGroupSerializer(NetBoxModelSerializer): scope_id = serializers.IntegerField(allow_null=True, required=False, default=None) scope = serializers.SerializerMethodField(read_only=True) vlan_count = serializers.IntegerField(read_only=True) - utilization = serializers.CharField(source='get_utilization', read_only=True) + utilization = serializers.CharField(read_only=True) class Meta: model = VLANGroup diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index f432e0e6b06..266461654bf 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -1,5 +1,6 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.db import transaction +from django.db.models import F from django.shortcuts import get_object_or_404 from django_pglocks import advisory_lock from drf_spectacular.utils import extend_schema @@ -146,7 +147,8 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet): class VLANGroupViewSet(NetBoxModelViewSet): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') serializer_class = serializers.VLANGroupSerializer filterset_class = filtersets.VLANGroupFilterSet diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 90bb73f5c19..7d4777da97f 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -114,15 +114,6 @@ def get_next_available_vid(self): return available_vids[0] return None - def get_utilization(self): - """ - Return the percentage of utilization for this vlan group. - """ - assigned_vlan = VLAN.objects.filter(group=self.id).count() - if assigned_vlan != 0: - return round(assigned_vlan / (self.max_vid - self.min_vid + 1) * 100, 2) - return 0.0 - class VLAN(PrimaryModel): """ diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index b2d9d5c2b7f..5d9828531d5 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -70,7 +70,7 @@ class VLANGroupTable(NetBoxTable): url_params={'group_id': 'pk'}, verbose_name='VLANs' ) - get_utilization = columns.UtilizationColumn( + utilization = columns.UtilizationColumn( orderable=False, verbose_name='Utilization' ) @@ -85,9 +85,9 @@ class Meta(NetBoxTable.Meta): model = VLANGroup fields = ( 'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description', - 'tags', 'created', 'last_updated', 'actions', 'get_utilization', + 'tags', 'created', 'last_updated', 'actions', 'utilization', ) - default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'get_utilization', 'description') + default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'description') # diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index a49c4aab3de..c9f488acfde 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,5 +1,5 @@ from django.contrib.contenttypes.models import ContentType -from django.db.models import Prefetch +from django.db.models import F, Prefetch from django.db.models.expressions import RawSQL from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse @@ -877,8 +877,9 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView): class VLANGroupListView(generic.ObjectListView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm table = tables.VLANGroupTable @@ -886,7 +887,9 @@ class VLANGroupListView(generic.ObjectListView): @register_model_view(VLANGroup) class VLANGroupView(generic.ObjectView): - queryset = VLANGroup.objects.all() + queryset = VLANGroup.objects.annotate( + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') def get_extra_context(self, request, instance): related_models = ( @@ -929,8 +932,9 @@ class VLANGroupBulkImportView(generic.BulkImportView): class VLANGroupBulkEditView(generic.BulkEditView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable form = forms.VLANGroupBulkEditForm @@ -938,8 +942,9 @@ class VLANGroupBulkEditView(generic.BulkEditView): class VLANGroupBulkDeleteView(generic.BulkDeleteView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable diff --git a/netbox/templates/ipam/vlangroup.html b/netbox/templates/ipam/vlangroup.html index 822b4a0460e..7decbb98330 100644 --- a/netbox/templates/ipam/vlangroup.html +++ b/netbox/templates/ipam/vlangroup.html @@ -43,10 +43,8 @@
VLAN Group
{{ object.min_vid }} - {{ object.max_vid }} - VLANs - - {{ vlans_count }} - + Utilization + {% utilization_graph object.utilization %} From ad7faa630b5509f8436bcf105d49f7befeee567b Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 13 May 2023 03:26:40 +0530 Subject: [PATCH 09/14] optimize queries --- netbox/ipam/api/views.py | 2 +- netbox/ipam/views.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 266461654bf..e3dce8b4533 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -148,7 +148,7 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet): class VLANGroupViewSet(NetBoxModelViewSet): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') serializer_class = serializers.VLANGroupSerializer filterset_class = filtersets.VLANGroupFilterSet diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index c9f488acfde..f0365c2ce1c 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -878,7 +878,7 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView): class VLANGroupListView(generic.ObjectListView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm @@ -933,7 +933,7 @@ class VLANGroupBulkImportView(generic.BulkImportView): class VLANGroupBulkEditView(generic.BulkEditView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable @@ -943,7 +943,7 @@ class VLANGroupBulkEditView(generic.BulkEditView): class VLANGroupBulkDeleteView(generic.BulkDeleteView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable From b9bb5a6b2976e5714faaeaf7742e6493981dc151 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 13 May 2023 03:28:05 +0530 Subject: [PATCH 10/14] merge fix --- netbox/templates/ipam/vlangroup.html | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/templates/ipam/vlangroup.html b/netbox/templates/ipam/vlangroup.html index 7decbb98330..e474cbd84ed 100644 --- a/netbox/templates/ipam/vlangroup.html +++ b/netbox/templates/ipam/vlangroup.html @@ -53,6 +53,7 @@
VLAN Group
{% plugin_left_page object %}
+ {% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/custom_fields.html' %} {% plugin_right_page object %}
From cf45f91b4f685da0641734c717fe7c7c26bc14d3 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 13 May 2023 03:31:56 +0530 Subject: [PATCH 11/14] adds round function for utilization to limit decimal --- netbox/ipam/api/views.py | 3 ++- netbox/ipam/views.py | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index e3dce8b4533..ce30ef11111 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -1,6 +1,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.db import transaction from django.db.models import F +from django.db.models.functions import Round from django.shortcuts import get_object_or_404 from django_pglocks import advisory_lock from drf_spectacular.utils import extend_schema @@ -148,7 +149,7 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet): class VLANGroupViewSet(NetBoxModelViewSet): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) ).prefetch_related('tags') serializer_class = serializers.VLANGroupSerializer filterset_class = filtersets.VLANGroupFilterSet diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index f0365c2ce1c..a9e9d587222 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,6 +1,7 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import F, Prefetch from django.db.models.expressions import RawSQL +from django.db.models.functions import Round from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.translation import gettext as _ @@ -878,7 +879,7 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView): class VLANGroupListView(generic.ObjectListView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm @@ -933,7 +934,7 @@ class VLANGroupBulkImportView(generic.BulkImportView): class VLANGroupBulkEditView(generic.BulkEditView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable @@ -943,7 +944,7 @@ class VLANGroupBulkEditView(generic.BulkEditView): class VLANGroupBulkDeleteView(generic.BulkDeleteView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group'), - utilization=F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100 + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable From 95d685b333e035258dfe26ed855c4dbda4ebc1fd Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Tue, 13 Jun 2023 20:41:43 +0530 Subject: [PATCH 12/14] fixed object view annotation --- netbox/ipam/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index a9e9d587222..804d1603ca4 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -889,7 +889,8 @@ class VLANGroupListView(generic.ObjectListView): @register_model_view(VLANGroup) class VLANGroupView(generic.ObjectView): queryset = VLANGroup.objects.annotate( - utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + vlan_count=count_related(VLAN, 'group'), + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) ).prefetch_related('tags') def get_extra_context(self, request, instance): From 4ce2bec8a8fa72e2261d57ca81730507fd06d91d Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Tue, 13 Jun 2023 20:55:53 +0530 Subject: [PATCH 13/14] consolidated queryset for utilization --- netbox/ipam/api/views.py | 5 +---- netbox/ipam/models/vlans.py | 4 +++- netbox/ipam/querysets.py | 15 ++++++++++++++- netbox/ipam/views.py | 20 ++++---------------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index ce30ef11111..4dd1d3cfe55 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -147,10 +147,7 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet): class VLANGroupViewSet(NetBoxModelViewSet): - queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group'), - utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) - ).prefetch_related('tags') + queryset = VLANGroup.objects.get_utilization().prefetch_related('tags') serializer_class = serializers.VLANGroupSerializer filterset_class = filtersets.VLANGroupFilterSet diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 7d4777da97f..da504ded2ac 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -9,7 +9,7 @@ from dcim.models import Interface from ipam.choices import * from ipam.constants import * -from ipam.querysets import VLANQuerySet +from ipam.querysets import VLANQuerySet, VLANGroupQuerySet from netbox.models import OrganizationalModel, PrimaryModel from virtualization.models import VMInterface @@ -63,6 +63,8 @@ class VLANGroup(OrganizationalModel): help_text=_('Highest permissible ID of a child VLAN') ) + objects = VLANGroupQuerySet.as_manager() + class Meta: ordering = ('name', 'pk') # Name may be non-unique constraints = ( diff --git a/netbox/ipam/querysets.py b/netbox/ipam/querysets.py index 9f4463f61e8..8b0647025a3 100644 --- a/netbox/ipam/querysets.py +++ b/netbox/ipam/querysets.py @@ -1,8 +1,10 @@ from django.contrib.contenttypes.models import ContentType -from django.db.models import Q +from django.db.models import F, Q from django.db.models.expressions import RawSQL +from django.db.models.functions import Round from utilities.querysets import RestrictedQuerySet +from utilities.utils import count_related class PrefixQuerySet(RestrictedQuerySet): @@ -30,6 +32,17 @@ def annotate_hierarchy(self): ) +class VLANGroupQuerySet(RestrictedQuerySet): + def get_utilization(self, *args, **kwargs): + from .models import VLAN + + return self.annotate( + vlan_count=count_related(VLAN, 'group'), + utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) + ) + + + class VLANQuerySet(RestrictedQuerySet): def get_for_device(self, device): diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index e03c0ec3e1b..bc83f654f1a 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -887,10 +887,7 @@ def get_children(self, request, parent): # class VLANGroupListView(generic.ObjectListView): - queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group'), - utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) - ).prefetch_related('tags') + queryset = VLANGroup.objects.get_utilization().prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm table = tables.VLANGroupTable @@ -898,10 +895,7 @@ class VLANGroupListView(generic.ObjectListView): @register_model_view(VLANGroup) class VLANGroupView(generic.ObjectView): - queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group'), - utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) - ).prefetch_related('tags') + queryset = VLANGroup.objects.get_utilization().prefetch_related('tags') def get_extra_context(self, request, instance): related_models = ( @@ -943,20 +937,14 @@ class VLANGroupBulkImportView(generic.BulkImportView): class VLANGroupBulkEditView(generic.BulkEditView): - queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group'), - utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) - ).prefetch_related('tags') + queryset = VLANGroup.objects.get_utilization().prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable form = forms.VLANGroupBulkEditForm class VLANGroupBulkDeleteView(generic.BulkDeleteView): - queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group'), - utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2) - ).prefetch_related('tags') + queryset = VLANGroup.objects.get_utilization().prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable From be13fd46b72f7673cf25f2813f3c05f7ab50d74c Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Tue, 13 Jun 2023 21:05:36 +0530 Subject: [PATCH 14/14] lint fixes --- netbox/ipam/querysets.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/ipam/querysets.py b/netbox/ipam/querysets.py index 8b0647025a3..7cc6ea4b323 100644 --- a/netbox/ipam/querysets.py +++ b/netbox/ipam/querysets.py @@ -42,7 +42,6 @@ def get_utilization(self, *args, **kwargs): ) - class VLANQuerySet(RestrictedQuerySet): def get_for_device(self, device):