NetBox Scope Switcher
Pick your scope once — tenant, region, site, tag, whatever you configure — and every list in NetBox narrows to it, with the filters cascading on each other.
netbox-scope-switcher adds one compact, configurable selector to the top
navigation bar. Choose values across any number of scope dimensions (grouped
however you like) and, as you move between sections (Devices, Prefixes, VLANs,
Sites, …), each list view is automatically scoped to your selection.
It generalizes
netbox-tenant-switcher:
tenant is just the default dimension.
Screenshots
Features
- Configurable, grouped dimensions. Scope by tenant, tenant group, region,
site group, site, location, tag, or any filter you declare in
PLUGINS_CONFIG— arranged under your own group headings. No code changes. - Cascading dependent filters. Selecting values in one dimension narrows the option lists of the others, in both directions: pick a Tenant Group and only its tenants remain; pick a Tenant and Regions/Sites/Racks shrink to where that tenant is present. Powered by NetBox's own filtersets (so tree descendants and every relationship are honoured), with no hard-coded model knowledge.
- Token-style control. One dropdown with a section per dimension: selected
values shown as removable chips, a
+ addpicker with instant search, anAnyplaceholder, aNoneoption (for objects with no value), per-dimension and global clear. Chips stay name-sorted. No external JS dependencies. - Localized. Dimension labels come straight from each model's NetBox
verbose_name, and the service words are translated via NetBox's catalog, so the panel follows the active UI language automatically. - Resizable & viewport-bounded panel. Drag the corner grip to resize (the size is remembered for the session); the panel never grows past the screen and scrolls internally.
- Honest URLs. By default the plugin issues a single redirect that adds the
filter params to the address bar, so links are shareable, NetBox's own filter
panel shows them, and Clear filters behaves predictably. A
silentmode is available. - Per-scope applicability. Each dimension is applied only on list views whose filterset actually supports it — a prefixes list may scope by tenant and tag but not region — computed by introspection, not hard-coding. The control dims when nothing applies to the current page.
- Combining semantics: several values within a dimension are OR-combined;
different dimensions are AND-combined;
Nonemaps to?param=null. - Permission-aware. Only values the user may view are listed and selectable, and scoping only ever narrows results — NetBox object permissions still apply on top.
- No models, no migrations. Selection lives in the session.
Compatibility
| Plugin version | NetBox version | Python |
|---|---|---|
| 1.0.x | 4.6 | 3.10 – 3.12 |
Developed and verified against NetBox 4.6, using only stable plugin APIs
(PluginTemplateExtension.navbar() / head(), plugin middleware). The CI matrix
(.github/workflows/ci.yml) additionally exercises 4.4 and 4.5.
Installation
source /opt/netbox/venv/bin/activate
pip install netbox-scope-switcher
Enable it in configuration.py:
PLUGINS = ["netbox_scope_switcher"]
Restart NetBox (sudo systemctl restart netbox netbox-rq). No migrations needed.
Docker (netbox-docker)
See deploy/ for a ready-to-use Dockerfile-Plugins,
docker-compose.override.yml, and plugins.py.
Configuration
Out of the box the plugin scopes by tenant only (matching
netbox-tenant-switcher). To configure dimensions and grouping, set
PLUGINS_CONFIG:
PLUGINS_CONFIG = {
"netbox_scope_switcher": {
"mode": "redirect", # or "silent"
"scopes": [
{"param": "tenant_group_id", "model": "tenancy.TenantGroup", "group": "Tenant"},
{"param": "tenant_id", "model": "tenancy.Tenant", "group": "Tenant"},
{"param": "region_id", "model": "dcim.Region", "group": "Location"},
{"param": "site_group_id", "model": "dcim.SiteGroup", "group": "Location"},
{"param": "site_id", "model": "dcim.Site", "group": "Location"},
{"param": "location_id", "model": "dcim.Location", "group": "Location"},
{"param": "tag", "model": "extras.Tag", "group": "Tag",
"value_field": "slug"},
],
}
}
PLUGINS_CONFIG keys
| Key | Type | Default | Description |
|---|---|---|---|
scopes |
list | tenant only | Ordered list of scope dimensions (below). |
mode |
string | redirect |
redirect (add params to the URL via a 302) or silent (rewrite the request in place). |
Each entry in scopes:
| Field | Required | Default | Description |
|---|---|---|---|
param |
yes | — | GET parameter of the filter to apply (e.g. tenant_id, tag). |
model |
yes | — | app_label.ModelName the dropdown values come from. |
group |
no | — | Group heading to list this dimension under (translated via NetBox). |
label |
no | model verbose name | Section heading. Omit it to follow the active UI language. |
value_field |
no | pk |
Value to put in the param: pk or slug (tags filter by slug). |
The configuration is validated at startup: an unknown model or field raises a
clear ImproperlyConfigured error on load, rather than a 500 at runtime.
How it works
- Navbar widget (
template_content.py) — aPluginTemplateExtensionrenders the control + a section per dimension vianavbar(); CSS/JS are injected once viahead(). Options are fetched from the values endpoint on open (so they can cascade); only the staticNoneoption is server-rendered. - Set endpoint (
views.py) —GET /plugins/scope-switcher/set/stores the chosen values per dimension in the session and redirects back.nextis validated against the current host (no open redirects); every value is checked against the user's view permission. - Values endpoint (
views.py) —GET /plugins/scope-switcher/values/<param>/?q=…&<other>=…returns a permission-scoped, cascaded, searchable JSON option list. - Cascade (
cascade.py) — narrows a dimension's options to those consistent with the current selection in the others. A forward pass filters a model by every other scope its own filterset supports (Site by Region, Rack by Location, …); a reverse pass handles the "upward" direction by pivoting through a bridge model that has a FK to the target and whose filterset does support the source (Site bridges Region↔Tenant, Tenant bridges Tenant Group↔Tenant, …). - Applicability (
applicability.py) — introspects the current list view's filterset (get_filters()/base_filters) to decide which configured params it supports; used to dim the control and to choose what to apply. - Middleware (
middleware.py) — forObjectListViewpages, appends one?param=<value>per selected value for each supported, not-already-present dimension.redirectmode issues a single 302;silentmode rewritesrequest.GET. API, GraphQL, and HTMX requests are skipped; existing query params (pagination, sort, per_page) are preserved.
Differences from netbox-tenant-switcher
netbox-tenant-switcher |
netbox-scope-switcher |
|
|---|---|---|
| Dimensions | tenant only (hard-coded) | any, configurable and grouped |
| Cascade | — | filters narrow each other, both directions |
| Control | one tenant field | one control, a section + chips per dimension |
| Localization | — | labels/service words follow the UI language |
| URL handling | redirect | redirect (default) or silent |
| Session state | list of tenant ids | {param: [values]} dict |
Migrating
pip uninstall netbox-tenant-switcherand remove it fromPLUGINS.pip install netbox-scope-switcher, add"netbox_scope_switcher"toPLUGINS.- Do nothing else for identical behaviour — the default config is the tenant
scope. Add more dimensions to
PLUGINS_CONFIGwhen you want them.
Sessions do not carry over (different key/shape); users simply re-pick their scope once.
Testing
Tests live in netbox_scope_switcher/tests/ and run inside a NetBox checkout:
python netbox/netbox/manage.py test netbox_scope_switcher -v 2
See .github/workflows/ci.yml for the full CI setup.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file netbox_scope_switcher-1.0.1.tar.gz.
File metadata
- Download URL: netbox_scope_switcher-1.0.1.tar.gz
- Upload date:
- Size: 34.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
774d6c87c7e0c396f77a8f99109f67f29312b61c2b96d425f71f2c1f4c708631
|
|
| MD5 |
6ac6ef209aea88cde0c280e12e511f02
|
|
| BLAKE2b-256 |
0d1854dc07e51737b55dd698339bdb1d8855df076d48fc25c1fdbe4bd4d63596
|
File details
Details for the file netbox_scope_switcher-1.0.1-py3-none-any.whl.
File metadata
- Download URL: netbox_scope_switcher-1.0.1-py3-none-any.whl
- Upload date:
- Size: 36.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27297283d99f589bfe0e5dcd3c722ff5f311e54eab7b002e1a9413827b3f58dd
|
|
| MD5 |
98178b518069e0ca108f93bf2c4bf392
|
|
| BLAKE2b-256 |
906d9e39daa0ca2d04ea3ba287ba2295123215056fadb63b3623e3f6fd237595
|