Skip to content

Commit

Permalink
More work on netbox-community#1523 (natural ordering for interfaces)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremystretch committed Sep 22, 2017
1 parent d7b0ba5 commit a010f74
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 21 deletions.
42 changes: 23 additions & 19 deletions netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 6 additions & 2 deletions netbox/dcim/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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]
)

0 comments on commit a010f74

Please sign in to comment.