-
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 toArrayColumnbut keep the column namevid_ranges_listto 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 astrwith no spaces).VLANGroup.vid_ranges_listremains 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_itemslist property.
Additional context / references
- Background plugin work that motivated this (spacing control):
ranges_to_text_listimplementation 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)