Fixes #1173: Tweak interface manager to fall back to naive ordering

This commit is contained in:
Jeremy Stretch 2017-05-12 16:10:18 -04:00
parent 67282882fa
commit c9d3cf301e

View File

@ -812,13 +812,13 @@ class InterfaceManager(models.Manager):
def order_naturally(self, method=IFACE_ORDERING_POSITION): def order_naturally(self, method=IFACE_ORDERING_POSITION):
""" """
Naturally order interfaces by their name and numeric position. The sort method must be one of the defined Naturally order interfaces by their type and numeric position. The sort method must be one of the defined
IFACE_ORDERING_CHOICES (typically indicated by a parent Device's DeviceType). IFACE_ORDERING_CHOICES (typically indicated by a parent Device's DeviceType).
To order interfaces naturally, the `name` field is split into five distinct components: leading text (name), To order interfaces naturally, the `name` field is split into six distinct components: leading text (type),
slot, subslot, position, channel, and virtual circuit: slot, subslot, position, channel, and virtual circuit:
{name}{slot}/{subslot}/{position}:{channel}.{vc} {type}{slot}/{subslot}/{position}:{channel}.{vc}
Components absent from the interface name are ignored. For example, an interface named GigabitEthernet0/1 would Components absent from the interface name are ignored. For example, an interface named GigabitEthernet0/1 would
be parsed as follows: be parsed as follows:
@ -830,16 +830,17 @@ class InterfaceManager(models.Manager):
channel = None channel = None
vc = 0 vc = 0
The chosen sorting method will determine which fields are ordered first in the query. The original `name` field is taken as a whole to serve as a fallback in the event interfaces do not match any of
the prescribed fields.
""" """
queryset = self.get_queryset() queryset = self.get_queryset()
sql_col = '{}.name'.format(queryset.model._meta.db_table) sql_col = '{}.name'.format(queryset.model._meta.db_table)
ordering = { ordering = {
IFACE_ORDERING_POSITION: ('_slot', '_subslot', '_position', '_channel', '_vc', '_name'), IFACE_ORDERING_POSITION: ('_slot', '_subslot', '_position', '_channel', '_vc', '_type', 'name'),
IFACE_ORDERING_NAME: ('_name', '_slot', '_subslot', '_position', '_channel', '_vc'), IFACE_ORDERING_NAME: ('_type', '_slot', '_subslot', '_position', '_channel', '_vc', 'name'),
}[method] }[method]
return queryset.extra(select={ return queryset.extra(select={
'_name': "SUBSTRING({} FROM '^([^0-9]+)')".format(sql_col), '_type': "SUBSTRING({} FROM '^([^0-9]+)')".format(sql_col),
'_slot': "CAST(SUBSTRING({} FROM '([0-9]+)\/[0-9]+\/[0-9]+(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col), '_slot': "CAST(SUBSTRING({} FROM '([0-9]+)\/[0-9]+\/[0-9]+(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col),
'_subslot': "CAST(SUBSTRING({} FROM '([0-9]+)\/[0-9]+(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col), '_subslot': "CAST(SUBSTRING({} FROM '([0-9]+)\/[0-9]+(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col),
'_position': "CAST(SUBSTRING({} FROM '([0-9]+)(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col), '_position': "CAST(SUBSTRING({} FROM '([0-9]+)(:[0-9]+)?(\.[0-9]+)?$') AS integer)".format(sql_col),