-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
NetBox version
v4.4.2
Feature type
Change to existing functionality
Proposed functionality
Introduce a helper that returns a list of human‑readable range strings so callers can control spacing and presentation without re‑implementing range logic:
ranges_to_text_list(ranges: Iterable[NumericRange]) -> list[str]
Returns items like["5-10", "25-30"]
using the same inclusive semantics thatranges_to_string()
currently applies.
Refactor the existing ranges_to_string()
implementation to build on the new helper while preserving its current output (comma‑separated, no spaces), e.g.:
def ranges_to_string(ranges):
return ",".join(ranges_to_text_list(ranges))
Finally, update the VLAN Group list to render VID ranges using ArrayColumn
so the UI shows the standard comma‑and‑space formatting (", "
), improving readability and aligning with other list displays.
Use case
Today, utilities.data.ranges_to_string()
emits no spaces between items (e.g., "5-10,25-30"
). This is correct for some contexts, but it makes it hard to reuse when a space‑separated presentation is desired (for example, table displays or human‑facing messages). Adding ranges_to_text_list()
lets call sites choose their own joiner, and lets tables use ArrayColumn
(which already renders with ", "
) for consistent UI.
Database changes
None.
External dependencies
None.
Proposed change (implementation notes)
- Add helper in
utilities/data.py
from typing import Iterable
from django.db.backends.postgresql.psycopg_any import NumericRange
def ranges_to_text_list(ranges: Iterable[NumericRange]) -> list[str]:
"""
Convert NumericRange values to human-friendly inclusive strings ["lo-hi", ...].
Mirrors ranges_to_string() semantics.
"""
if not ranges:
return []
items: list[str] = []
for r in ranges:
# Compute inclusive bounds regardless of how the DB range is stored.
lower = r.lower if getattr(r, "lower_inc", True) else r.lower + 1
upper = r.upper if getattr(r, "upper_inc", False) else r.upper - 1
# If you prefer singletons like "5" instead of "5-5", uncomment:
# if lower == upper:
# items.append(f"{lower}")
# else:
items.append(f"{lower}-{upper}")
return items
- Refactor
ranges_to_string()
(backward compatible)
def ranges_to_string(ranges):
if not ranges:
return ""
return ",".join(ranges_to_text_list(ranges))
- VLAN Group model
Keep the existing string property (e.g.,vid_ranges_list
) to avoid breaking any consumers. Add a new list‑returning property for table use:
# ipam/models/vlans.py
from utilities.data import ranges_to_text_list
@property
def vid_ranges_items(self) -> list[str]:
return ranges_to_text_list(self.vid_ranges)
- VLAN Group table
Switch the column toArrayColumn
but keep the column namevid_ranges_list
to preserve saved table configs; point it at the new list property:
# ipam/tables/vlans.py
from netbox.tables import columns
# Old:
# vid_ranges_list = tables.Column(verbose_name=_('VID Ranges'), orderable=False)
# New:
vid_ranges_list = columns.ArrayColumn(
accessor='vid_ranges_items',
verbose_name=_('VID Ranges'),
orderable=False,
)
Backwards compatibility
ranges_to_string()
output and signature remain unchanged (still returns astr
with no spaces).VLANGroup.vid_ranges_list
remains available (still astr
) to avoid breaking any code or saved table configurations that reference its column name. The table change keeps the same column name while sourcing from a newvid_ranges_items
list property.
Additional context / references
- Background plugin work that motivated this (spacing control):
ranges_to_text_list
implementation in netbox‑acls:
pheus/netbox-acls@da406f9
Before / After (table rendering example)
- Before:
VID Ranges
→1-99,200-299
- After:
VID Ranges
→1-99, 200-299
(space after comma viaArrayColumn
)