mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-11 21:10:29 +01:00
Allow customization of queryset get_for_* functions #11534
Closed
opened 2025-12-29 21:46:29 +01:00 by adam
·
5 comments
No Branch/Tag Specified
main
update-changelog-comments-docs
feature-removal-issue-type
20911-dropdown
20239-plugin-menu-classes-mutable-state
21097-graphql-id-lookups
feature
fix_module_substitution
20923-dcim-templates
20044-elevation-stuck-lightmode
feature-ip-prefix-link
v4.5-beta1-release
20068-import-moduletype-attrs
20766-fix-german-translation-code-literals
20378-del-script
7604-filter-modifiers-v3
circuit-swap
12318-case-insensitive-uniqueness
20637-improve-device-q-filter
20660-script-load
19724-graphql
20614-update-ruff
14884-script
02496-max-page
19720-macaddress-interface-generic-relation
19408-circuit-terminations-export-templates
20203-openapi-check
fix-19669-api-image-download
7604-filter-modifiers
19275-fixes-interface-bulk-edit
fix-17794-get_field_value_return_list
11507-show-aggregate-and-rir-on-api
9583-add_column_specific_search_field_to_tables
v4.5.0
v4.4.10
v4.4.9
v4.5.0-beta1
v4.4.8
v4.4.7
v4.4.6
v4.4.5
v4.4.4
v4.4.3
v4.4.2
v4.4.1
v4.4.0
v4.3.7
v4.4.0-beta1
v4.3.6
v4.3.5
v4.3.4
v4.3.3
v4.3.2
v4.3.1
v4.3.0
v4.2.9
v4.3.0-beta2
v4.2.8
v4.3.0-beta1
v4.2.7
v4.2.6
v4.2.5
v4.2.4
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.11
v4.1.10
v4.1.9
v4.1.8
v4.2-beta1
v4.1.7
v4.1.6
v4.1.5
v4.1.4
v4.1.3
v4.1.2
v4.1.1
v4.1.0
v4.0.11
v4.0.10
v4.0.9
v4.1-beta1
v4.0.8
v4.0.7
v4.0.6
v4.0.5
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v3.7.8
v3.7.7
v4.0-beta2
v3.7.6
v3.7.5
v4.0-beta1
v3.7.4
v3.7.3
v3.7.2
v3.7.1
v3.7.0
v3.6.9
v3.6.8
v3.6.7
v3.7-beta1
v3.6.6
v3.6.5
v3.6.4
v3.6.3
v3.6.2
v3.6.1
v3.6.0
v3.5.9
v3.6-beta2
v3.5.8
v3.6-beta1
v3.5.7
v3.5.6
v3.5.5
v3.5.4
v3.5.3
v3.5.2
v3.5.1
v3.5.0
v3.4.10
v3.4.9
v3.5-beta2
v3.4.8
v3.5-beta1
v3.4.7
v3.4.6
v3.4.5
v3.4.4
v3.4.3
v3.4.2
v3.4.1
v3.4.0
v3.3.10
v3.3.9
v3.4-beta1
v3.3.8
v3.3.7
v3.3.6
v3.3.5
v3.3.4
v3.3.3
v3.3.2
v3.3.1
v3.3.0
v3.2.9
v3.2.8
v3.3-beta2
v3.2.7
v3.3-beta1
v3.2.6
v3.2.5
v3.2.4
v3.2.3
v3.2.2
v3.2.1
v3.2.0
v3.1.11
v3.1.10
v3.2-beta2
v3.1.9
v3.2-beta1
v3.1.8
v3.1.7
v3.1.6
v3.1.5
v3.1.4
v3.1.3
v3.1.2
v3.1.1
v3.1.0
v3.0.12
v3.0.11
v3.0.10
v3.1-beta1
v3.0.9
v3.0.8
v3.0.7
v3.0.6
v3.0.5
v3.0.4
v3.0.3
v3.0.2
v3.0.1
v3.0.0
v2.11.12
v3.0-beta2
v2.11.11
v2.11.10
v3.0-beta1
v2.11.9
v2.11.8
v2.11.7
v2.11.6
v2.11.5
v2.11.4
v2.11.3
v2.11.2
v2.11.1
v2.11.0
v2.10.10
v2.10.9
v2.11-beta1
v2.10.8
v2.10.7
v2.10.6
v2.10.5
v2.10.4
v2.10.3
v2.10.2
v2.10.1
v2.10.0
v2.9.11
v2.10-beta2
v2.9.10
v2.10-beta1
v2.9.9
v2.9.8
v2.9.7
v2.9.6
v2.9.5
v2.9.4
v2.9.3
v2.9.2
v2.9.1
v2.9.0
v2.9-beta2
v2.8.9
v2.9-beta1
v2.8.8
v2.8.7
v2.8.6
v2.8.5
v2.8.4
v2.8.3
v2.8.2
v2.8.1
v2.8.0
v2.7.12
v2.7.11
v2.7.10
v2.7.9
v2.7.8
v2.7.7
v2.7.6
v2.7.5
v2.7.4
v2.7.3
v2.7.2
v2.7.1
v2.7.0
v2.6.12
v2.6.11
v2.6.10
v2.6.9
v2.7-beta1
Solcon-2020-01-06
v2.6.8
v2.6.7
v2.6.6
v2.6.5
v2.6.4
v2.6.3
v2.6.2
v2.6.1
v2.6.0
v2.5.13
v2.5.12
v2.6-beta1
v2.5.11
v2.5.10
v2.5.9
v2.5.8
v2.5.7
v2.5.6
v2.5.5
v2.5.4
v2.5.3
v2.5.2
v2.5.1
v2.5.0
v2.4.9
v2.5-beta2
v2.4.8
v2.5-beta1
v2.4.7
v2.4.6
v2.4.5
v2.4.4
v2.4.3
v2.4.2
v2.4.1
v2.4.0
v2.3.7
v2.4-beta1
v2.3.6
v2.3.5
v2.3.4
v2.3.3
v2.3.2
v2.3.1
v2.3.0
v2.2.10
v2.3-beta2
v2.2.9
v2.3-beta1
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.6
v2.2-beta2
v2.1.5
v2.2-beta1
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.10
v2.1-beta1
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
v2.0-beta3
v1.9.6
v1.9.5
v2.0-beta2
v1.9.4-r1
v1.9.3
v2.0-beta1
v1.9.2
v1.9.1
v1.9.0-r1
v1.8.4
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.7.3
v1.7.2-r1
v1.7.1
v1.7.0
v1.6.3
v1.6.2-r1
v1.6.1-r1
1.6.1
v1.6.0
v1.5.2
v1.5.1
v1.5.0
v1.4.2
v1.4.1
v1.4.0
v1.3.2
v1.3.1
v1.3.0
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.7-r1
v1.0.7
v1.0.6
v1.0.5
v1.0.4
v1.0.3-r1
v1.0.3
1.0.0
Labels
Clear labels
beta
breaking change
complexity: high
complexity: low
complexity: medium
needs milestone
netbox
pending closure
plugin candidate
pull-request
severity: high
severity: low
severity: medium
status: accepted
status: backlog
status: blocked
status: duplicate
status: needs owner
status: needs triage
status: revisions needed
status: under review
topic: GraphQL
topic: Internationalization
topic: OpenAPI
topic: UI/UX
topic: cabling
topic: event rules
topic: htmx navigation
topic: industrialization
topic: migrations
topic: plugins
topic: scripts
topic: templating
topic: testing
type: bug
type: deprecation
type: documentation
type: feature
type: housekeeping
type: translation
Mirrored from GitHub Pull Request
No Label
type: feature
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/netbox#11534
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Omripresent on GitHub (Aug 26, 2025).
NetBox version
v4.1.11
Feature type
New functionality
Proposed functionality
Netbox has an opinionated way of scoping VLAN to devices/VMs when done by locations, site groups, and regions, forcing the location and its ancestors VLAN groups to be assignable to a given device/VM.
I would be useful for some deployments to allow customization of that functionality by allowing admins to define their desired logic with functions in extras.py that if set can override the builtin get_for_* functions in the relevant querysets.
Our current workaround is to customize the docker image by replacing the querysets.py files where needed, this workaround comes at the cost of comparing the modified files on every upgrade to avoid using old code in other parts of the file.
Use case
Use case 1 - Parent location sees all:
There are times when devices in a given location can be assigned VLANs associated with all descendant locations
Use case 2 - Isolated locations:
In some cases admins might need to make sure locations are fully isolated and would need to match the exclusive location alone and no other VLANs
Database changes
N/A
External dependencies
N/A
@jeremystretch commented on GitHub (Aug 28, 2025):
@Omripresent could you please elaborate on your specific use case? It's not clear based solely on the code snippets you've shared above.
@Omripresent commented on GitHub (Aug 28, 2025):
Sorry for the lack of context. In a fabric (EVPN/VXLAN) deployment and the flexibility of VLAN/MAC mobility there are unique organization options we employ in our deployment.
For example in a fabric with device-1..3 each in their distinct location, that may be a cage or row in the physical datacenter.
loc-1 is the parent for both loc-2 and loc-3. and each VG is scoped to its respective location
The way Netbox is currently working the VLAN assignment options are as follows:
device-1 = [ vlan-1 ]
device-2 = [ vlan-1 vlan-2 ]
device-3 = [ vlan-1 vlan-3 ]
Referring to the 2 use cases I've mentioned originally, both apply to some of our environments, depending on certain conditions be it device role, tag assignment or custom field, we need to change the VLAN availability behavior.
For use case 1 expected VLAN scope availability:
device-1 = [ vlan-1 vlan-2 vlan-3 ]
device-2 = [ vlan-2 ]
device-3 = [ vlan-3 ]
For use case 2 expected VLAN scope availability:
device-1 = [ vlan-1 ]
device-2 = [ vlan-2 ]
device-3 = [ vlan-3 ]
Those use cases are relevant to a subset of our overall deployment and having the flexibility to tailor the querysets to each use case would be extremely helpful as more specialized requirements are being asked of us.
@jnovinger commented on GitHub (Sep 15, 2025):
Hi @Omripresent,
Regarding the extensibility approach you described for overriding queryset methods, this isn't something we're planning to implement in NetBox core. We maintain these methods as part of NetBox's stable API surface.
That said, we'd like to better understand your specific use cases to see if there might be other approaches that could work within NetBox's existing architecture. The conditional logic you described seems to depend on installation-specific attributes (roles, tags, custom fields), but understanding the underlying operational patterns might help identify a more generic solution that could benefit the broader NetBox community. Could you clarify a few technical details?
You mentioned being able to "create the functions that we can overload the existing ones" similar to
extras.py. Could you clarify what extensibility mechanism you're referring to? Or are you suggesting this as a new mechanism?How are you currently modifying the queryset methods in your deployment (it's not clear to me from the code snippets above)? To be clear, I mean, what do the modified queryset methods look like?
For the conditional logic you described (based on "device role, tag assignment or custom field"), could you provide examples of what specific attributes you're checking? This would help us understand if there are generic patterns that could work across different NetBox installations.
When you mention "parent sees all descendants" vs "strict isolation", are these behaviors you need simultaneously in the same installation, or alternatives you'd choose between?
The main challenge is that core NetBox can't assume specific device roles, tags, or custom fields exist across different installations.
@Omripresent commented on GitHub (Sep 15, 2025):
Hi @jnovinger,
I'll try to answer your questions as best as I can.
I was thinking similar to the
JINJA2_FILTERSvariable in extras.py we could have the option to define queryset get functions that the core Netbox can use where applicable.For example, let's say I want to override the VLANQuerySet get_for_device function. I would need to define the function and reference it in a variable. Something along the lines of:
Then in the queryset function itself some functionality along the lines of:
I'm not allowed to share the specific code, but the change is to
VLANQuerySet.get_for_deviceand the logic looking at a custom field value of the device's tenant and changes the location scope matching to location.get_descendants instead of get_ancestors.We haven't implemented any of our other use cases yet. Those stem from new regulatory requirements that we're working on implementing
See point 2, but there are a few other use cases we're actively working on supporting that will require further modifications.
We're running a single global instance and will require all of the above depending on either device role, custom field, or other possible data point. Since we have multiple network architecture designs depending on the business entity and regulatory requirements, we have to support the different edge cases in a single installation.
I'll look into L2VPN for that implementation, but most of our EVPN/VXLAN are single site to support horizontal growth at scale, all devices participating in a fabric are in the same Netbox location to allow the VLAN assignments correctly.
@jeremystretch commented on GitHub (Oct 6, 2025):
@Omripresent thanks for sharing this. It seems that the root of your problem is attempting to treat a VLAN group in different ways depending on the context. Unfortunately this isn't something we're able to support.
VLAN groups exist to denote the geographic scope of an L2 domain (i.e. region-wide, site-wide, etc.). A VLAN group which is scoped to a location is always considered available for all child locations. Where this is not the case, a VLAN group must instead be scoped to the applicable child location.
Admittedly, this can be limiting in certain scenarios, and discussion around improving L2 modeling in general is ongoing. However, the proposed mechanism of introducing conditional logic for queries is almost certain to introduce more challenges than it solves, so I have to decline this specific proposal.
That said, I encourage you to start a discussion and elaborate further on your specific use case(s) and needs. Once they've been fleshed out further, we may be able to build on other recent discussions around improved L2 domain modeling to figure out potential solutions.
Thanks again for the idea!