From a010f7439d4598df4d0edfe6db0118e801aed39c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 22 Sep 2017 16:18:43 -0400 Subject: [PATCH] More work on #1523 (natural ordering for interfaces) --- netbox/dcim/models.py | 42 +++++++++++++++++--------------- netbox/dcim/tests/test_models.py | 8 ++++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 52527cc1932..311f02e99ac 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -661,28 +661,32 @@ def order_naturally(self, method=IFACE_ORDERING_POSITION): """ sql_col = '{}.name'.format(self.model._meta.db_table) ordering = { - IFACE_ORDERING_POSITION: ('_slot', '_subslot', '_position', '_subposition', '_channel', '_vc', '_type', 'name'), - IFACE_ORDERING_NAME: ('_type', '_slot', '_subslot', '_position', '_subposition', '_channel', '_vc', 'name'), + IFACE_ORDERING_POSITION: ( + '_slot', '_subslot', '_position', '_subposition', '_channel', '_vc', '_type', '_id', 'name', + ), + IFACE_ORDERING_NAME: ( + '_type', '_slot', '_subslot', '_position', '_subposition', '_channel', '_vc', '_id', 'name', + ), }[method] + TYPE_RE = r"SUBSTRING({} FROM '^([^0-9]+)')" + ID_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)([0-9]+)$') AS integer)" + SLOT_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)([0-9]+)\/') AS integer)" + SUBSLOT_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+\/)([0-9]+)') AS integer)" + POSITION_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+\/){{2}}([0-9]+)') AS integer)" + SUBPOSITION_RE = r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+\/){{3}}([0-9]+)') AS integer)" + CHANNEL_RE = r"COALESCE(CAST(SUBSTRING({} FROM ':([0-9]+)(\.[0-9]+)?$') AS integer), 0)" + VC_RE = r"COALESCE(CAST(SUBSTRING({} FROM '\.([0-9]+)$') AS integer), 0)" + fields = { - '_type': RawSQL(r"SUBSTRING({} FROM '^([^0-9]+)')".format(sql_col), []), - '_slot': RawSQL(r"CAST(SUBSTRING({} FROM '^(?:[^0-9]+)([0-9]+)') AS integer)".format(sql_col), []), - '_subslot': RawSQL( - r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+)\/([0-9]+)') AS integer), 0)".format( - sql_col), [] - ), - '_position': RawSQL( - r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+\/){{2}}([0-9]+)') AS integer), 0)".format( - sql_col), [] - ), - '_subposition': RawSQL( - r"COALESCE(CAST(SUBSTRING({} FROM '^(?:[^0-9]+)(?:[0-9]+\/){{3}}([0-9]+)') AS integer), 0)".format( - sql_col), [] - ), - '_channel': RawSQL( - r"COALESCE(CAST(SUBSTRING({} FROM ':([0-9]+)(\.[0-9]+)?$') AS integer), 0)".format(sql_col), []), - '_vc': RawSQL(r"COALESCE(CAST(SUBSTRING({} FROM '\.([0-9]+)$') AS integer), 0)".format(sql_col), []), + '_type': RawSQL(TYPE_RE.format(sql_col), []), + '_id': RawSQL(ID_RE.format(sql_col), []), + '_slot': RawSQL(SLOT_RE.format(sql_col), []), + '_subslot': RawSQL(SUBSLOT_RE.format(sql_col), []), + '_position': RawSQL(POSITION_RE.format(sql_col), []), + '_subposition': RawSQL(SUBPOSITION_RE.format(sql_col), []), + '_channel': RawSQL(CHANNEL_RE.format(sql_col), []), + '_vc': RawSQL(VC_RE.format(sql_col), []), } return self.annotate(**fields).order_by(*ordering) diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index 00a4de28cd4..b4101cfd571 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -159,10 +159,14 @@ def test_interface_order_natural(self): device=device1, name='Ethernet1/3/2/1' ) + interface6 = Interface.objects.create( + device=device1, + name='Loopback1' + ) self.assertEqual( list(Interface.objects.all().order_naturally()), - [interface1, interface5, interface4, interface3, interface2] + [interface1, interface5, interface4, interface3, interface2, interface6] ) def test_interface_order_natural_subinterfaces(self): @@ -201,5 +205,5 @@ def test_interface_order_natural_subinterfaces(self): ) self.assertEqual( list(Interface.objects.all().order_naturally()), - [interface6, interface4, interface3, interface5, interface2, interface1] + [interface4, interface3, interface5, interface2, interface1, interface6] )