Skip to content

Object numbers (human-readable IDs)

Every object in Danbyte has a UUID primary key — globally unique, stable, safe in URLs, but not something you'd read out over the phone or stencil onto a cable. So alongside the UUID, each object also carries a numid: a short, sequential, per-tenant number. A cable physically tagged "27" can map to cable #27; tenant A's #30 and tenant B's #30 are different objects that never collide.

This makes Danbyte friendlier to operators and far easier to migrate onto from NetBox, where every object has exactly this kind of integer id.

How numbering works

  • Per tenant, per type. Each (tenant, object-type) pair has its own counter starting at 1. Devices, cables, prefixes, VLANs… each count independently within a tenant.
  • Allocated once, then stable. A number is assigned the first time an object is saved with a tenant set, and never changes afterward — editing, moving, or re-saving the object keeps its numid.
  • The UUID is still the key. numid is purely additive. Foreign keys, URLs, and tenant isolation all still run on the UUID; the number is a human-facing label on top.
  • Allocation is race-safe. The counter is advanced under a row lock, so two concurrent creates can't be handed the same number.

Numbers are surfaced as a Number column on list pages (toggle it in the Columns menu) and a Number field on detail pages.

The Cable label

Cables also gained a free-form label field (NetBox parity). A cable now renders by preference as its label, else #numid, else its UUID — so a cable never shows up as a bare UUID in a picker or a connection list.

The "Human-readable IDs" toggle

Settings → Deployment → Human-readable IDs controls whether the UI surfaces numid (the Number columns and fields). It's on by default.

The toggle is display-only

Numbering always happens per-tenant in the background regardless of the toggle — the switch only governs whether the number is shown in the interface. Turning it off doesn't stop allocation or change any object's number; turning it back on reveals the same numbers again.

Backfilling existing data

The numid field is allocated on save, and bulk inserts (bulk_create) skip save() to stay fast — so rows that predate the feature, or were imported in bulk, start out unnumbered. Assign them in one idempotent pass:

python manage.py assign_numids

It walks every tenant-scoped model, numbers any rows still missing a numid in creation order (1-based, no gaps), and advances each tenant/type counter so the next object created continues right where the backfill left off. Running it again is a no-op — already-numbered rows are left alone, so it's safe to re-run after any large import.

Run it after a fresh install or a bulk import

A migrate adds the column but doesn't backfill existing rows. After upgrading an instance that already has data — or after importing a batch via bulk_create / the import tools — run assign_numids once to number everything.

Which objects get a number

All directly tenant-scoped objects — Device, Cable, Prefix, IPAddress, Rack, VLAN, VRF, Circuit, Site, and the rest of the catalog and instance models.

Not numbered: catalog/choice rows that aren't tenant-scoped (e.g. statuses) and device-child objects that have no direct tenant of their own (interfaces, ports, cable terminations) — a numid needs a tenant to scope its counter against.