Introduce array_to_string() utility function; add port_list property to Service

This commit is contained in:
Jeremy Stretch 2020-09-21 13:31:38 -04:00
parent f97d8963f2
commit e77f1bdd85
5 changed files with 24 additions and 18 deletions

View File

@ -1,5 +1,4 @@
from collections import OrderedDict from collections import OrderedDict
from itertools import count, groupby
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
@ -22,7 +21,7 @@ from utilities.choices import ColorChoices
from utilities.fields import ColorField, NaturalOrderingField from utilities.fields import ColorField, NaturalOrderingField
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
from utilities.mptt import TreeManager 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 .devices import Device
from .power import PowerFeed from .power import PowerFeed
@ -642,9 +641,4 @@ class RackReservation(ChangeLoggedModel, CustomFieldModel):
@property @property
def unit_list(self): def unit_list(self):
""" return array_to_string(self.units)
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)

View File

@ -14,7 +14,7 @@ from dcim.models import Device, Interface
from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem
from extras.utils import extras_features from extras.utils import extras_features
from utilities.querysets import RestrictedQuerySet 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 virtualization.models import VirtualMachine, VMInterface
from .choices import * from .choices import *
from .constants import * from .constants import *
@ -1038,7 +1038,7 @@ class Service(ChangeLoggedModel, CustomFieldModel):
ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique
def __str__(self): 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): def get_absolute_url(self):
return reverse('ipam:service', args=[self.pk]) return reverse('ipam:service', args=[self.pk])
@ -1064,3 +1064,7 @@ class Service(ChangeLoggedModel, CustomFieldModel):
self.ports, self.ports,
self.description, self.description,
) )
@property
def port_list(self):
return array_to_string(self.ports)

View File

@ -1,13 +1,10 @@
<tr> <tr>
<td> <td><a href="{{ service.get_absolute_url }}">{{ service.name }}</a></td>
<a href="{{ service.get_absolute_url }}">{{ service.name }}</a> <td>{{ service.get_protocol_display }}</td>
</td> <td>{{ service.port_list }}</td>
<td>
{{ service.get_protocol_display }}/{{ service.port }}
</td>
<td> <td>
{% for ip in service.ipaddresses.all %} {% for ip in service.ipaddresses.all %}
<span>{{ ip.address.ip }}</span><br /> <a href="{{ ip.get_absolute_url }}">{{ ip.address.ip }}</a><br />
{% empty %} {% empty %}
<span class="text-muted">All IPs</span> <span class="text-muted">All IPs</span>
{% endfor %} {% endfor %}

View File

@ -63,7 +63,7 @@
</tr> </tr>
<tr> <tr>
<td>Ports</td> <td>Ports</td>
<td>{{ service.ports|join:", " }}</td> <td>{{ service.port_list }}</td>
</tr> </tr>
<tr> <tr>
<td>IP Addresses</td> <td>IP Addresses</td>

View File

@ -1,6 +1,7 @@
import datetime import datetime
import json import json
from collections import OrderedDict from collections import OrderedDict
from itertools import count, groupby
from django.core.serializers import serialize from django.core.serializers import serialize
from django.db.models import Count, OuterRef, Subquery from django.db.models import Count, OuterRef, Subquery
@ -282,6 +283,16 @@ def curry(_curried_func, *args, **kwargs):
return _curried 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 # Fake request object
# #