Skip to content

Conversation

@renatoalmeidaoliveira
Copy link
Contributor

Fixes: #18833 Inventory Item Bulk Import - 'InventoryItemImportForm' has no field named 'component_id'.

Root Cause:

In Django's BaseModelForm _post_clean method, an instance of the model is created with data from self.cleaned_data. After the model instantiation, the full_clean() method is executed on that model instance.
Since component_type is a field of the InventoryItem model, the execution of full_clean() on the instance was failing without being captured by any form validation method.

Solution:

In Django's form validation process, the clean_<fieldname>() methods are executed before the clean_form() method. Inside the clean_<fieldname>() method, there are no guarantees about which field names have already been processed and is available at self.cleaned_data.And to fully validate component_type use cases, the device, component_type, and component_name fields must be available.

To fix the validation process, the clean_component_name method was replaced by the clean method, and the fields component_name and component_type were removed from cleaned_data when incorrect data was provided.

@renatoalmeidaoliveira renatoalmeidaoliveira requested review from a team and jeremystretch and removed request for a team March 11, 2025 23:12
@renatoalmeidaoliveira
Copy link
Contributor Author

About the two remaining revisions:

When Django runs full_clean() in BaseForm it executes _clean_fields, _clean_form and _post_clean and in both _clean_fields and _clean_form the ValidationError exceptions are captured, added to the form errors, and not propagated full_clean code
But inside _post_clean Django tries to create an instance of the form's model and run full clean in that instatiated model _post_clean code

I tryed to edit the InventoryItem's clean method to avoid mutate the cleaned_field but it isn't working, even just adding a simple Exception at the beginnig of clean and it isn't executed, so changing that method may not work as expected
Another option I see could be changing the InventoryItemImportForm's 'component_type` to something that isn't a model field

Copy link
Member

@jeremystretch jeremystretch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get a ValueError exception when attempting to import with a component_type but no component_name specified: 'InventoryItemImportForm' has no field named 'component_id'.

Test data:

device,name,status,component_type
dmi01-akron-rtr01,item1,active,dcim.interface

@jeremystretch jeremystretch self-requested a review March 19, 2025 13:34
Copy link
Member

@jeremystretch jeremystretch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeremystretch jeremystretch merged commit bf1a9a6 into netbox-community:main Mar 19, 2025
3 checks passed
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inventory Item Bulk Import - 'InventoryItemImportForm' has no field named 'component_id'.

2 participants