diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index ce30ef111..4dd1d3cfe 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 7d4777da9..da504ded2 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -9,7 +9,7 @@ from django.utils.translation import gettext as _ 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 9f4463f61..8b0647025 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 @@ class PrefixQuerySet(RestrictedQuerySet): ) +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 e03c0ec3e..bc83f654f 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -887,10 +887,7 @@ class IPAddressRelatedIPsView(generic.ObjectChildrenView): # 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