From e77f1bdd850f087da615910a31827a020f024d0d Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 21 Sep 2020 13:31:38 -0400 Subject: [PATCH] Introduce array_to_string() utility function; add port_list property to Service --- netbox/dcim/models/racks.py | 10 ++-------- netbox/ipam/models.py | 8 ++++++-- netbox/templates/ipam/inc/service.html | 11 ++++------- netbox/templates/ipam/service.html | 2 +- netbox/utilities/utils.py | 11 +++++++++++ 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/netbox/dcim/models/racks.py b/netbox/dcim/models/racks.py index f09f8c828..102929476 100644 --- a/netbox/dcim/models/racks.py +++ b/netbox/dcim/models/racks.py @@ -1,5 +1,4 @@ from collections import OrderedDict -from itertools import count, groupby from django.conf import settings from django.contrib.auth.models import User @@ -22,7 +21,7 @@ from utilities.choices import ColorChoices from utilities.fields import ColorField, NaturalOrderingField from utilities.querysets import RestrictedQuerySet from utilities.mptt import TreeManager -from utilities.utils import serialize_object +from utilities.utils import array_to_string, serialize_object from .devices import Device from .power import PowerFeed @@ -642,9 +641,4 @@ class RackReservation(ChangeLoggedModel, CustomFieldModel): @property def unit_list(self): - """ - Express the assigned units as a string of summarized ranges. For example: - [0, 1, 2, 10, 14, 15, 16] => "0-2, 10, 14-16" - """ - group = (list(x) for _, x in groupby(sorted(self.units), lambda x, c=count(): next(c) - x)) - return ', '.join('-'.join(map(str, (g[0], g[-1])[:len(g)])) for g in group) + return array_to_string(self.units) diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 1146fab55..f34ed3749 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -14,7 +14,7 @@ from dcim.models import Device, Interface from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem from extras.utils import extras_features from utilities.querysets import RestrictedQuerySet -from utilities.utils import serialize_object +from utilities.utils import array_to_string, serialize_object from virtualization.models import VirtualMachine, VMInterface from .choices import * from .constants import * @@ -1038,7 +1038,7 @@ class Service(ChangeLoggedModel, CustomFieldModel): ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique def __str__(self): - return f'{self.name} ({self.get_protocol_display()}/{self.ports})' + return f'{self.name} ({self.get_protocol_display()}/{self.port_list})' def get_absolute_url(self): return reverse('ipam:service', args=[self.pk]) @@ -1064,3 +1064,7 @@ class Service(ChangeLoggedModel, CustomFieldModel): self.ports, self.description, ) + + @property + def port_list(self): + return array_to_string(self.ports) diff --git a/netbox/templates/ipam/inc/service.html b/netbox/templates/ipam/inc/service.html index 9611be175..9ece30da5 100644 --- a/netbox/templates/ipam/inc/service.html +++ b/netbox/templates/ipam/inc/service.html @@ -1,13 +1,10 @@ - - {{ service.name }} - - - {{ service.get_protocol_display }}/{{ service.port }} - + {{ service.name }} + {{ service.get_protocol_display }} + {{ service.port_list }} {% for ip in service.ipaddresses.all %} - {{ ip.address.ip }}
+ {{ ip.address.ip }}
{% empty %} All IPs {% endfor %} diff --git a/netbox/templates/ipam/service.html b/netbox/templates/ipam/service.html index f87a7a1a0..6a1489681 100644 --- a/netbox/templates/ipam/service.html +++ b/netbox/templates/ipam/service.html @@ -63,7 +63,7 @@ Ports - {{ service.ports|join:", " }} + {{ service.port_list }} IP Addresses diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index fbb7830e2..52a951555 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -1,6 +1,7 @@ import datetime import json from collections import OrderedDict +from itertools import count, groupby from django.core.serializers import serialize from django.db.models import Count, OuterRef, Subquery @@ -282,6 +283,16 @@ def curry(_curried_func, *args, **kwargs): return _curried +def array_to_string(array): + """ + Generate an efficient, human-friendly string from a set of integers. Intended for use with ArrayField. + For example: + [0, 1, 2, 10, 14, 15, 16] => "0-2, 10, 14-16" + """ + group = (list(x) for _, x in groupby(sorted(array), lambda x, c=count(): next(c) - x)) + return ', '.join('-'.join(map(str, (g[0], g[-1])[:len(g)])) for g in group) + + # # Fake request object #