Default values for custom_fields are ignored in API when custom_fields section is used #10778

Closed
opened 2025-12-29 21:35:50 +01:00 by adam · 3 comments
Owner

Originally created by @antonvdl on GitHub (Feb 19, 2025).

Originally assigned to: @atownson on GitHub.

Deployment Type

Self-hosted

NetBox Version

v4.2.3

Python Version

3.12

Steps to Reproduce

  1. Create multiple custom_fields with object type IPAM > Prefix
  • primary_subnet, type: boolean, required: yes, default value: true
  • ripe_admin, type: text, required: no, default value: "xxx-RIPE"
  • ripe_tech, type: text, required:no
  • ripe_netname, type: text, required: no
  1. Create a new prefix using API without custom_fields
    { "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6 }
  2. Create a new prefix using API with only "primary_subnet" as custom_field
    { "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6, "custom_fields": { "primary_subnet": true } }
  3. Create a new prefix using API with only "ripe_netname" as custom_field
    { "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6, "custom_fields": { "ripe_netname": "test" } }

Expected Behavior

  1. Custom fields are created
  2. Prefix is created with default values for custom_fields primary_subnet and ripe_admin. Other custom_fields are null
  3. Prefix is created with supplied value for custom_field primary_subnet, default value for ripe_admin. Other custom_fields are null
  4. Prefix is created with default values for custom_fields primary_subnet and ripe_admin. ripe_netname gets the supplied value and ripe_tech remains null

Observed Behavior

As soon as a custom_fields section is available in the POST Body then the default values for all custom_fields are ignored.
When I do not send the custom_fields section at all then the default values are used correctly.

  1. Custom fields are created (OK)
  2. Prefix is created with default values for primary_subnet and ripe_admin (OK)
  3. Prefix is created with primary_subnet set to true but other custom_fields are empty -> default value for ripe_admin is ignored
  4. Prefix is not created because primary_subnet (required) is not supplied -> default value for primary_subnet is ignored
Originally created by @antonvdl on GitHub (Feb 19, 2025). Originally assigned to: @atownson on GitHub. ### Deployment Type Self-hosted ### NetBox Version v4.2.3 ### Python Version 3.12 ### Steps to Reproduce 1. Create multiple custom_fields with object type IPAM > Prefix - primary_subnet, type: boolean, required: yes, default value: true - ripe_admin, type: text, required: no, default value: "xxx-RIPE" - ripe_tech, type: text, required:no - ripe_netname, type: text, required: no 2. Create a new prefix using API without custom_fields `{ "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6 }` 3. Create a new prefix using API with only "primary_subnet" as custom_field `{ "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6, "custom_fields": { "primary_subnet": true } }` 4. Create a new prefix using API with only "ripe_netname" as custom_field `{ "prefix": "10.0.0.0/24", "status": "active", "description": "Test prefix", "vlan": "147", "is_pool": false, "tenant": 6, "custom_fields": { "ripe_netname": "test" } }` ### Expected Behavior 1. Custom fields are created 2. Prefix is created with default values for custom_fields primary_subnet and ripe_admin. Other custom_fields are null 3. Prefix is created with supplied value for custom_field primary_subnet, default value for ripe_admin. Other custom_fields are null 4. Prefix is created with default values for custom_fields primary_subnet and ripe_admin. ripe_netname gets the supplied value and ripe_tech remains null ### Observed Behavior As soon as a custom_fields section is available in the POST Body then the default values for all custom_fields are ignored. When I do not send the custom_fields section at all then the default values are used correctly. 1. Custom fields are created (OK) 2. Prefix is created with default values for primary_subnet and ripe_admin (OK) 3. Prefix is created with primary_subnet set to true but other custom_fields are empty -> default value for ripe_admin is ignored 4. Prefix is not created because primary_subnet (required) is not supplied -> default value for primary_subnet is ignored
adam added the type: bugstatus: acceptedseverity: low labels 2025-12-29 21:35:50 +01:00
adam closed this issue 2025-12-29 21:35:50 +01:00
Author
Owner

@atownson commented on GitHub (Mar 17, 2025):

The same is also true for scripts that create instances of objects. Omitting the custom_field_data dict creates the object with the custom field default values as expected, but including the custom_field_data dict and omitting a required field does not set a value for the custom field.

You can deal with this in scripts like such (which might indicate how to solve this issue):

ip_address = IPAddress(
	address = '192.168.0.1/32'
)
ip_address.populate_custom_field_defaults()
ip_address.custom_field_data['my_custom_field'] = 'hard-coded value'
ip_address.full_clean()
ip_address.save()
@atownson commented on GitHub (Mar 17, 2025): The same is also true for scripts that create instances of objects. Omitting the `custom_field_data` dict creates the object with the custom field default values as expected, but including the `custom_field_data` dict and omitting a required field does not set a value for the custom field. You can deal with this in scripts like such (which might indicate how to solve this issue): ``` ip_address = IPAddress( address = '192.168.0.1/32' ) ip_address.populate_custom_field_defaults() ip_address.custom_field_data['my_custom_field'] = 'hard-coded value' ip_address.full_clean() ip_address.save() ```
Author
Owner

@atownson commented on GitHub (Apr 7, 2025):

I believe the issue is that the default values are not populated in CustomFieldsDataField.to_internal_value().

@atownson commented on GitHub (Apr 7, 2025): I believe the issue is that the default values are not populated in [CustomFieldsDataField.to_internal_value()](https://github.com/netbox-community/netbox/blob/92317248a36c0c57ecfde97d9690cad35fe47d81/netbox/extras/api/customfields.py#L70).
Author
Owner

@atownson commented on GitHub (Apr 7, 2025):

I can submit a PR for this.

@atownson commented on GitHub (Apr 7, 2025): I can submit a PR for this.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10778