mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-11 21:10:29 +01:00
Calculated Jinja2 based CustomFields #7620
Closed
opened 2025-12-29 20:26:06 +01:00 by adam
·
6 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
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/netbox#7620
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 @PieterL75 on GitHub (Feb 8, 2023).
NetBox version
v3.4.4
Feature type
New functionality
Proposed functionality
Create a custom field of the type 'Calculated'
This custom field is composed of a Jinja2 template that gives the ability to format the data of the object to an custom presentation.
It should provide the ability to represent create a string, a badge, a %graph, markdown, ...
Use case
There is a lot of a data in one model (device), and most of can be shown in a table column.
This custom field will create a way to merge multiple columns into one, or create a column with data that is not visible in the GUI (ex: number of interfaces)
https://github.com/netbox-community/netbox/issues/6347 will give even more fields to merge into a custom view
It will create the ability to provide fully customizable view, with the need to update the core of the code.
Database changes
No response
External dependencies
No response
@jeremystretch commented on GitHub (Feb 8, 2023):
IMO this wouldn't be an appropriate use of custom fields, as it's a pretty stark violation of the separation between data and presentation. Custom fields exist specifically to hold additional data about an object, not to to display existing data in an alternative format. I can appreciate the underlying use case, but I don't think custom fields are the right solution for it.
Edit to add: It seems like your focus is primarily on table columns. Maybe what you're really after is a way to inject custom columns?
@PieterL75 commented on GitHub (Feb 8, 2023):
My proposal is mainly for columns, but I can imagine that it is also useful in the Deviceview or even in API results (not the badges, but the numbers)
I suppose you can see better solution than a custom field (your (net)box is bigger than my (net)box), but in my little box, that seemed a good idea :-)
@ryanmerolle commented on GitHub (Feb 10, 2023):
Relates to #8217
Other DCIM tools offer jinja custom_fields, and so this will likely come up from time to time.
If you are using custom fields for links to other tools like I was, I migrated to custom_links which allow for Jinja logic in the link text and url. It solved most of my use case.
My only other use case was for generating interface descriptions since I throw in circuit info and peer device/interface info into descriptions. I just achieve that by including the jinja logic in my config templates.
@jeremystretch commented on GitHub (Feb 11, 2023):
I'll elaborate on my explanation above.
My understanding of the intent here is to expose as an object attribute some value that is rendered (or "computed") from one or more other attributes of that object. As a very contrived example, let's say we want to include a field in the REST API representation of a site that concatenates the name of its region with its own name. Suppose we want to do this using a simple Jinja2 filter:
So for example, a site named "Raleigh" in a region named "North Carolina" would look like this:
There are two reasons we wouldn't want to use a custom field for this:
For example, there should never be an instance where an API consumer would need to set the value of the
region-and-nameattribute` directly: Instead, it's influenced by the values of the fields it references. Custom field values by contrast are mutable and can be set directly by an API consumer.One key implication of this distinction is that computed attributes do not need to be stored per instance; we only need to define a per-model definition, which can be replicated for each instance. In this example, we just create a single attribute object tying our Jinja2 code to the site model. This allows us to render the attribute for every site.
The only reason I can see to store the computed value for each instance would be as a performance optimization (essentially caching the rendered output). But considering the overhead associated with keeping these values up to date combined with the additional complexity of supporting read-only custom fields, this seems unlikely to be worthwhile except in very complex scenarios.
Beyond the technical implementation, we must also consider the practical use case for such attributes: Given that APIs are intended to be consumed programmatically, what practical use cases can we identify that cannot be satisfied with the data already being provided. (As in the above example, the region and site names are already provided, and the client could render the custom attribute value independently.) Further, we would generally want to stop short of rendering any particular markup (e.g. HTML) as it could severely limit the practical application of the data being provided.
Again, it feels like the intended use case here is specifically for the user interface, which is a valid consideration as it cannot be consumed programmatically. If anything, I would propose that the preferred implementation would be some mechanism by which custom attributes can be registered at the model level, and potentially conveyed as table columns and other elements in the user interface.
@PieterL75 commented on GitHub (Feb 11, 2023):
I understand your point on the API part. CustomFields are not the right place to store this kind of formatting, as they are intended to store data related to the instance of the model. Each object of that model should be able to store different values in the CustomField.
My proposal does indeed require a different approach.
You're more in favor of a 'CustomColumn' or 'CustomAttribute' that links to a model. That attribute can be made available in the 'Configure Table' list, and it can also be returned as an attribute to a model in the API.
There could be different types of these (Text, Integer, URL, Badge, ProgressBar, ...)
@jeremystretch commented on GitHub (Mar 16, 2023):
I'm going to close this out as the specific proposal herein is untenable, but I encourage anyone interested to submit a new FR proposing a feasible implementation of the desired functionality. This will likely require the introduction of a new model, which should be detailed accordingly.