mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 17:08:41 -06:00
* Update serializers.py * Update vlans.py * Update vlans.py * Update vlangroup.html * Update vlans.py * Update vlans.py * Update serializers.py * adds db annotation to calculate utilization * optimize queries * merge fix * adds round function for utilization to limit decimal * fixed object view annotation * consolidated queryset for utilization * lint fixes * Renamed manager method to annotate_utilization() for consistency with other managers --------- Co-authored-by: Abhimanyu Saharan <desk.abhimanyu@gmail.com>
This commit is contained in:
parent
62bdb90f61
commit
7419a8e112
@ -218,12 +218,13 @@ class VLANGroupSerializer(NetBoxModelSerializer):
|
|||||||
scope_id = serializers.IntegerField(allow_null=True, required=False, default=None)
|
scope_id = serializers.IntegerField(allow_null=True, required=False, default=None)
|
||||||
scope = serializers.SerializerMethodField(read_only=True)
|
scope = serializers.SerializerMethodField(read_only=True)
|
||||||
vlan_count = serializers.IntegerField(read_only=True)
|
vlan_count = serializers.IntegerField(read_only=True)
|
||||||
|
utilization = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VLANGroup
|
model = VLANGroup
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'name', 'slug', 'scope_type', 'scope_id', 'scope', 'min_vid', 'max_vid',
|
'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 = []
|
validators = []
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||||
from django.db import transaction
|
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.shortcuts import get_object_or_404
|
||||||
from django_pglocks import advisory_lock
|
from django_pglocks import advisory_lock
|
||||||
from drf_spectacular.utils import extend_schema
|
from drf_spectacular.utils import extend_schema
|
||||||
@ -145,9 +147,7 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class VLANGroupViewSet(NetBoxModelViewSet):
|
class VLANGroupViewSet(NetBoxModelViewSet):
|
||||||
queryset = VLANGroup.objects.annotate(
|
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||||
vlan_count=count_related(VLAN, 'group')
|
|
||||||
).prefetch_related('tags')
|
|
||||||
serializer_class = serializers.VLANGroupSerializer
|
serializer_class = serializers.VLANGroupSerializer
|
||||||
filterset_class = filtersets.VLANGroupFilterSet
|
filterset_class = filtersets.VLANGroupFilterSet
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from django.utils.translation import gettext as _
|
|||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
from ipam.choices import *
|
from ipam.choices import *
|
||||||
from ipam.constants import *
|
from ipam.constants import *
|
||||||
from ipam.querysets import VLANQuerySet
|
from ipam.querysets import VLANQuerySet, VLANGroupQuerySet
|
||||||
from netbox.models import OrganizationalModel, PrimaryModel
|
from netbox.models import OrganizationalModel, PrimaryModel
|
||||||
from virtualization.models import VMInterface
|
from virtualization.models import VMInterface
|
||||||
|
|
||||||
@ -63,6 +63,8 @@ class VLANGroup(OrganizationalModel):
|
|||||||
help_text=_('Highest permissible ID of a child VLAN')
|
help_text=_('Highest permissible ID of a child VLAN')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
objects = VLANGroupQuerySet.as_manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name', 'pk') # Name may be non-unique
|
ordering = ('name', 'pk') # Name may be non-unique
|
||||||
constraints = (
|
constraints = (
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import Count, OuterRef, Q, Subquery, Value
|
from django.db.models import Count, F, OuterRef, Q, Subquery, Value
|
||||||
from django.db.models.expressions import RawSQL
|
from django.db.models.expressions import RawSQL
|
||||||
|
from django.db.models.functions import Round
|
||||||
|
|
||||||
from utilities.querysets import RestrictedQuerySet
|
from utilities.querysets import RestrictedQuerySet
|
||||||
|
from utilities.utils import count_related
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ASNRangeQuerySet',
|
'ASNRangeQuerySet',
|
||||||
@ -54,6 +56,17 @@ class PrefixQuerySet(RestrictedQuerySet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VLANGroupQuerySet(RestrictedQuerySet):
|
||||||
|
|
||||||
|
def annotate_utilization(self):
|
||||||
|
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):
|
class VLANQuerySet(RestrictedQuerySet):
|
||||||
|
|
||||||
def get_for_device(self, device):
|
def get_for_device(self, device):
|
||||||
|
@ -70,6 +70,10 @@ class VLANGroupTable(NetBoxTable):
|
|||||||
url_params={'group_id': 'pk'},
|
url_params={'group_id': 'pk'},
|
||||||
verbose_name='VLANs'
|
verbose_name='VLANs'
|
||||||
)
|
)
|
||||||
|
utilization = columns.UtilizationColumn(
|
||||||
|
orderable=False,
|
||||||
|
verbose_name='Utilization'
|
||||||
|
)
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='ipam:vlangroup_list'
|
url_name='ipam:vlangroup_list'
|
||||||
)
|
)
|
||||||
@ -81,9 +85,9 @@ class VLANGroupTable(NetBoxTable):
|
|||||||
model = VLANGroup
|
model = VLANGroup
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description',
|
'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description',
|
||||||
'tags', 'created', 'last_updated', 'actions',
|
'tags', 'created', 'last_updated', 'actions', 'utilization',
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description')
|
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'description')
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
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.db.models.expressions import RawSQL
|
||||||
|
from django.db.models.functions import Round
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@ -882,9 +883,7 @@ class IPAddressRelatedIPsView(generic.ObjectChildrenView):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class VLANGroupListView(generic.ObjectListView):
|
class VLANGroupListView(generic.ObjectListView):
|
||||||
queryset = VLANGroup.objects.annotate(
|
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||||
vlan_count=count_related(VLAN, 'group')
|
|
||||||
)
|
|
||||||
filterset = filtersets.VLANGroupFilterSet
|
filterset = filtersets.VLANGroupFilterSet
|
||||||
filterset_form = forms.VLANGroupFilterForm
|
filterset_form = forms.VLANGroupFilterForm
|
||||||
table = tables.VLANGroupTable
|
table = tables.VLANGroupTable
|
||||||
@ -892,7 +891,7 @@ class VLANGroupListView(generic.ObjectListView):
|
|||||||
|
|
||||||
@register_model_view(VLANGroup)
|
@register_model_view(VLANGroup)
|
||||||
class VLANGroupView(generic.ObjectView):
|
class VLANGroupView(generic.ObjectView):
|
||||||
queryset = VLANGroup.objects.all()
|
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
related_models = (
|
related_models = (
|
||||||
@ -934,18 +933,14 @@ class VLANGroupBulkImportView(generic.BulkImportView):
|
|||||||
|
|
||||||
|
|
||||||
class VLANGroupBulkEditView(generic.BulkEditView):
|
class VLANGroupBulkEditView(generic.BulkEditView):
|
||||||
queryset = VLANGroup.objects.annotate(
|
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||||
vlan_count=count_related(VLAN, 'group')
|
|
||||||
)
|
|
||||||
filterset = filtersets.VLANGroupFilterSet
|
filterset = filtersets.VLANGroupFilterSet
|
||||||
table = tables.VLANGroupTable
|
table = tables.VLANGroupTable
|
||||||
form = forms.VLANGroupBulkEditForm
|
form = forms.VLANGroupBulkEditForm
|
||||||
|
|
||||||
|
|
||||||
class VLANGroupBulkDeleteView(generic.BulkDeleteView):
|
class VLANGroupBulkDeleteView(generic.BulkDeleteView):
|
||||||
queryset = VLANGroup.objects.annotate(
|
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
|
||||||
vlan_count=count_related(VLAN, 'group')
|
|
||||||
)
|
|
||||||
filterset = filtersets.VLANGroupFilterSet
|
filterset = filtersets.VLANGroupFilterSet
|
||||||
table = tables.VLANGroupTable
|
table = tables.VLANGroupTable
|
||||||
|
|
||||||
|
@ -42,6 +42,10 @@
|
|||||||
<th scope="row">Permitted VIDs</th>
|
<th scope="row">Permitted VIDs</th>
|
||||||
<td>{{ object.min_vid }} - {{ object.max_vid }}</td>
|
<td>{{ object.min_vid }} - {{ object.max_vid }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Utilization</th>
|
||||||
|
<td>{% utilization_graph object.utilization %}</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user