Config Template Rendering - Issue by access custom fields #8038

Closed
opened 2025-12-29 20:31:36 +01:00 by adam · 3 comments
Owner

Originally created by @jonasnieberle on GitHub (May 11, 2023).

NetBox version

v3.5.0

Python version

3.8

Steps to Reproduce

Create Config Template:

{{ device.name }}
{{ device.id }}
{{ device.serial }}
Custom Field output:
{{ device.custom_fields.version }}
{{ device.custom_fields.domain }}

Create Custom Fields

Version --> Text Custom Field
Domain --> Text Custom Field

Set Domain and Version Field by Device.

Template for debugging and more informations

{{ device.name }}
{{ device.id }}
{{ device.serial }}
Print Custom Fields
{{ device.custom_fields }}
Custom Field output - not working
{{ device.custom_fields.version }}
{{ device.custom_fields.domain }}
Loop Custom Fields
{% for field in device.custom_fields %}
{{ field }}:
{{ field.id }}
{% endfor %}

Expected Behavior

Config Template should render following output:

switch1
1
KSHWSHNXBSW
Print Custom Fields
17.01.23
test.domain

Observed Behavior

Config Template render following output:

switch1
1
KSHWSHNXBSW
Print Custom Fields


--> Custom Field Variables not exist.

If you render the debug template, I see that the id for the custom field output ist the general id for the custom field. But the value for the custom fields are stored by the device, not in extras/custom-fields ... I think the device object have an reference or something else to the custom field. I think the device object stores the custom field values, which I can use in the template. Same behavior by interface objects and custom fields.

switch1
1
KSHWSHNXBSW
Print Custom Fields
<RestrictedQuerySet [<CustomField: Version>, <CustomField: Domain>]>
Custom Field output - not working


Loop Custom Fields
Version
1
Domain
2
Originally created by @jonasnieberle on GitHub (May 11, 2023). ### NetBox version v3.5.0 ### Python version 3.8 ### Steps to Reproduce # Create Config Template: ```bash {{ device.name }} {{ device.id }} {{ device.serial }} Custom Field output: {{ device.custom_fields.version }} {{ device.custom_fields.domain }} ``` # Create Custom Fields Version --> Text Custom Field Domain --> Text Custom Field Set Domain and Version Field by Device. # Template for debugging and more informations ```bash {{ device.name }} {{ device.id }} {{ device.serial }} Print Custom Fields {{ device.custom_fields }} Custom Field output - not working {{ device.custom_fields.version }} {{ device.custom_fields.domain }} Loop Custom Fields {% for field in device.custom_fields %} {{ field }}: {{ field.id }} {% endfor %} ``` ### Expected Behavior Config Template should render following output: ```bash switch1 1 KSHWSHNXBSW Print Custom Fields 17.01.23 test.domain ``` ### Observed Behavior Config Template render following output: ```bash switch1 1 KSHWSHNXBSW Print Custom Fields ``` --> Custom Field Variables not exist. If you render the debug template, I see that the id for the custom field output ist the general id for the custom field. But the value for the custom fields are stored by the device, not in extras/custom-fields ... I think the device object have an reference or something else to the custom field. I think the device object stores the custom field values, which I can use in the template. Same behavior by interface objects and custom fields. ```bash switch1 1 KSHWSHNXBSW Print Custom Fields <RestrictedQuerySet [<CustomField: Version>, <CustomField: Domain>]> Custom Field output - not working Loop Custom Fields Version 1 Domain 2 ```
adam closed this issue 2025-12-29 20:31:36 +01:00
Author
Owner

@kkthxbye-code commented on GitHub (May 11, 2023):

https://docs.netbox.dev/en/stable/customization/custom-fields/#custom-fields-in-templates

Several features within NetBox, such as export templates and webhooks, utilize Jinja2 templating. For convenience, objects which support custom field assignment expose custom field data through the cf property. This is a bit cleaner than accessing custom field data through the actual field (custom_field_data).

For example, a custom field named foo123 on the Site model is accessible on an instance as {{ site.cf.foo123 }}.

{{ device.name }}
{{ device.id }}
{{ device.serial }}
Custom Field output:
{{ device.cf.version }}
{{ device.cf.domain }}

Closing as invalid. Remember to read the documentation.

@kkthxbye-code commented on GitHub (May 11, 2023): https://docs.netbox.dev/en/stable/customization/custom-fields/#custom-fields-in-templates >Several features within NetBox, such as export templates and webhooks, utilize Jinja2 templating. For convenience, objects which support custom field assignment expose custom field data through the cf property. This is a bit cleaner than accessing custom field data through the actual field (custom_field_data). >For example, a custom field named foo123 on the Site model is accessible on an instance as {{ site.cf.foo123 }}. ``` {{ device.name }} {{ device.id }} {{ device.serial }} Custom Field output: {{ device.cf.version }} {{ device.cf.domain }} ``` Closing as invalid. Remember to read the documentation.
Author
Owner

@Djo91 commented on GitHub (May 11, 2023):

https://docs.netbox.dev/en/stable/customization/custom-fields/#custom-fields-in-templates

Several features within NetBox, such as export templates and webhooks, utilize Jinja2 templating. For convenience, objects which support custom field assignment expose custom field data through the cf property. This is a bit cleaner than accessing custom field data through the actual field (custom_field_data).

For example, a custom field named foo123 on the Site model is accessible on an instance as {{ site.cf.foo123 }}.

{{ device.name }}
{{ device.id }}
{{ device.serial }}
Custom Field output:
{{ device.cf.version }}
{{ device.cf.domain }}

Closing as invalid. Remember to read the documentation.

Hello,

Is there a list including all methods/variables that can be natively used in a Config Templates and understood by the renderer ?

For example, I know that you can use the method "device.modules.all()" to get all modules information attached to the device :

Config Template :

{% for card in device.modules.all() %}
{% set card_position = "0/" ~ card.module_bay.name.split(' ')[1] %}
board add {{ card_position }} {{ card.module_type }}
{% endfor %}

Rendered Config :

 board add 0/1 H902GPHF
 board add 0/4 H902FLHF

But I don't find a method / variable to get all cables information attached to an interface (I tried with device.interfaces.all()) :

Config Template :

{% for interface_uplink in device.interfaces.all() %}
Cable ID : {{ interface_uplink.cable }}
Cable type : {{ interface_uplink.cable.type }}
Cable length : {{ interface_uplink.cable.length }}
Cable Terminaison B device : {{ interface_uplink.cable.b_terminations??? }} ==> How to get information "display": "olt-val92-06", ?
Cable Terminaison B interface : {{ interface_uplink.cable.b_terminations[0] }} ==> API get : "display": "0/8/1 (UPLINK 0/8/1)",
{% endfor %}

API GET Result (cable #4)

{
    "id": 4,
    "url": "https://myserver/api/dcim/cables/4/",
    "display": "#4",
    "type": "mmf",
    "a_terminations": [
        {
            ...
        }
    ],
    "b_terminations": [
        {
            "object_type": "dcim.interface",
            "object_id": 428,
            "object": {
                "id": 428,
                "url": "https://myserver/api/dcim/interfaces/428/",
                "display": "0/8/1 (UPLINK 0/8/1)",
                "device": {
                    "id": 87849,
                    "url": "https://myserver/api/dcim/devices/87849/",
                    "display": "olt-val92-06",
                    "name": "olt-val92-06"
                },
                "name": "0/8/1",
                "cable": 4,
                "_occupied": true
            }
        }
    ]
}

Rendered Config :

Cable ID : #4
Cable type : mmf
Cable length : 2.00
Cable Terminaison B device : 
Cable Terminaison B interface : 0/8/1 (UPLINK 0/8/1)

I tried many settings, without success.

@Djo91 commented on GitHub (May 11, 2023): > https://docs.netbox.dev/en/stable/customization/custom-fields/#custom-fields-in-templates > > > Several features within NetBox, such as export templates and webhooks, utilize Jinja2 templating. For convenience, objects which support custom field assignment expose custom field data through the cf property. This is a bit cleaner than accessing custom field data through the actual field (custom_field_data). > > > For example, a custom field named foo123 on the Site model is accessible on an instance as {{ site.cf.foo123 }}. > > ``` > {{ device.name }} > {{ device.id }} > {{ device.serial }} > Custom Field output: > {{ device.cf.version }} > {{ device.cf.domain }} > ``` > > Closing as invalid. Remember to read the documentation. Hello, Is there a list including all methods/variables that can be natively used in a Config Templates and understood by the renderer ? For example, I know that you can use the method "**device.modules.all()**" to get all modules information attached to the device : Config Template : ``` {% for card in device.modules.all() %} {% set card_position = "0/" ~ card.module_bay.name.split(' ')[1] %} board add {{ card_position }} {{ card.module_type }} {% endfor %} ``` Rendered Config : ``` board add 0/1 H902GPHF board add 0/4 H902FLHF ``` But I don't find a method / variable to get all cables information attached to an interface (I tried with **device.interfaces.all()**) : Config Template : ``` {% for interface_uplink in device.interfaces.all() %} Cable ID : {{ interface_uplink.cable }} Cable type : {{ interface_uplink.cable.type }} Cable length : {{ interface_uplink.cable.length }} Cable Terminaison B device : {{ interface_uplink.cable.b_terminations??? }} ==> How to get information "display": "olt-val92-06", ? Cable Terminaison B interface : {{ interface_uplink.cable.b_terminations[0] }} ==> API get : "display": "0/8/1 (UPLINK 0/8/1)", {% endfor %} ``` API GET Result (cable #4) ``` { "id": 4, "url": "https://myserver/api/dcim/cables/4/", "display": "#4", "type": "mmf", "a_terminations": [ { ... } ], "b_terminations": [ { "object_type": "dcim.interface", "object_id": 428, "object": { "id": 428, "url": "https://myserver/api/dcim/interfaces/428/", "display": "0/8/1 (UPLINK 0/8/1)", "device": { "id": 87849, "url": "https://myserver/api/dcim/devices/87849/", "display": "olt-val92-06", "name": "olt-val92-06" }, "name": "0/8/1", "cable": 4, "_occupied": true } } ] } ``` Rendered Config : ``` Cable ID : #4 Cable type : mmf Cable length : 2.00 Cable Terminaison B device : Cable Terminaison B interface : 0/8/1 (UPLINK 0/8/1) ``` I tried many settings, without success.
Author
Owner

@Djo91 commented on GitHub (Jun 5, 2023):

I've found my reply here :
https://github.com/netbox-community/netbox/discussions/12746

Regards ;)

@Djo91 commented on GitHub (Jun 5, 2023): I've found my reply here : https://github.com/netbox-community/netbox/discussions/12746 Regards ;)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#8038