From c9d3cf301ebd7fb89dd04003e7ac0348ad7db853 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 12 May 2017 16:10:18 -0400 Subject: [PATCH] Fixes #1173: Tweak interface manager to fall back to naive ordering --- netbox/dcim/models.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index fa1407487..59d7a0ef2 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -812,13 +812,13 @@ class InterfaceManager(models.Manager): 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). - 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: - {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 be parsed as follows: @@ -830,16 +830,17 @@ class InterfaceManager(models.Manager): channel = None 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() sql_col = '{}.name'.format(queryset.model._meta.db_table) ordering = { - IFACE_ORDERING_POSITION: ('_slot', '_subslot', '_position', '_channel', '_vc', '_name'), - IFACE_ORDERING_NAME: ('_name', '_slot', '_subslot', '_position', '_channel', '_vc'), + IFACE_ORDERING_POSITION: ('_slot', '_subslot', '_position', '_channel', '_vc', '_type', 'name'), + IFACE_ORDERING_NAME: ('_type', '_slot', '_subslot', '_position', '_channel', '_vc', 'name'), }[method] 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), '_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),