Fixes #13047: Add annotate_asn_count() to ASNRange manager

This commit is contained in:
Jeremy Stretch 2023-06-29 15:35:53 -04:00
parent 4355ee6407
commit 5f0922713f
4 changed files with 35 additions and 13 deletions

View File

@ -4,6 +4,7 @@ from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from ipam.fields import ASNField from ipam.fields import ASNField
from ipam.querysets import ASNRangeQuerySet
from netbox.models import OrganizationalModel, PrimaryModel from netbox.models import OrganizationalModel, PrimaryModel
__all__ = ( __all__ = (
@ -37,6 +38,8 @@ class ASNRange(OrganizationalModel):
null=True null=True
) )
objects = ASNRangeQuerySet.as_manager()
class Meta: class Meta:
ordering = ('name',) ordering = ('name',)
verbose_name = 'ASN range' verbose_name = 'ASN range'

View File

@ -1,9 +1,33 @@
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Count, OuterRef, Q, Subquery, Value
from django.db.models.expressions import RawSQL from django.db.models.expressions import RawSQL
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
__all__ = (
'ASNRangeQuerySet',
'PrefixQuerySet',
'VLANQuerySet',
)
class ASNRangeQuerySet(RestrictedQuerySet):
def annotate_asn_counts(self):
"""
Annotate the number of ASNs which appear within each range.
"""
from .models import ASN
# Because ASN does not have a foreign key to ASNRange, we create a fake column "_" with a consistent value
# that we can use to count ASNs and return a single value per ASNRange.
asns = ASN.objects.filter(
asn__gte=OuterRef('start'),
asn__lte=OuterRef('end')
).order_by().annotate(_=Value(1)).values('_').annotate(c=Count('*')).values('c')
return self.annotate(asn_count=Subquery(asns))
class PrefixQuerySet(RestrictedQuerySet): class PrefixQuerySet(RestrictedQuerySet):

View File

@ -21,10 +21,8 @@ class ASNRangeTable(TenancyColumnsMixin, NetBoxTable):
tags = columns.TagColumn( tags = columns.TagColumn(
url_name='ipam:asnrange_list' url_name='ipam:asnrange_list'
) )
asn_count = columns.LinkedCountColumn( asn_count = tables.Column(
viewname='ipam:asn_list', verbose_name=_('ASNs')
url_params={'asn_id': 'pk'},
verbose_name=_('ASN Count')
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
@ -59,7 +57,8 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
verbose_name=_('Provider Count') verbose_name=_('Provider Count')
) )
sites = columns.ManyToManyColumn( sites = columns.ManyToManyColumn(
linkify_item=True linkify_item=True,
verbose_name=_('Sites')
) )
comments = columns.MarkdownColumn() comments = columns.MarkdownColumn()
tags = columns.TagColumn( tags = columns.TagColumn(

View File

@ -198,7 +198,7 @@ class RIRBulkDeleteView(generic.BulkDeleteView):
# #
class ASNRangeListView(generic.ObjectListView): class ASNRangeListView(generic.ObjectListView):
queryset = ASNRange.objects.all() queryset = ASNRange.objects.annotate_asn_counts()
filterset = filtersets.ASNRangeFilterSet filterset = filtersets.ASNRangeFilterSet
filterset_form = forms.ASNRangeFilterForm filterset_form = forms.ASNRangeFilterForm
table = tables.ASNRangeTable table = tables.ASNRangeTable
@ -247,18 +247,14 @@ class ASNRangeBulkImportView(generic.BulkImportView):
class ASNRangeBulkEditView(generic.BulkEditView): class ASNRangeBulkEditView(generic.BulkEditView):
queryset = ASNRange.objects.annotate( queryset = ASNRange.objects.annotate_asn_counts()
site_count=count_related(Site, 'asns')
)
filterset = filtersets.ASNRangeFilterSet filterset = filtersets.ASNRangeFilterSet
table = tables.ASNRangeTable table = tables.ASNRangeTable
form = forms.ASNRangeBulkEditForm form = forms.ASNRangeBulkEditForm
class ASNRangeBulkDeleteView(generic.BulkDeleteView): class ASNRangeBulkDeleteView(generic.BulkDeleteView):
queryset = ASNRange.objects.annotate( queryset = ASNRange.objects.annotate_asn_counts()
site_count=count_related(Site, 'asns')
)
filterset = filtersets.ASNRangeFilterSet filterset = filtersets.ASNRangeFilterSet
table = tables.ASNRangeTable table = tables.ASNRangeTable