Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Conversation

renatoalmeidaoliveira
Copy link
Collaborator

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
Collaborator 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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