mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 01:49:35 -06:00
Validate related object is dictionary
Elements of the "related objects list" are passed to the `prep_related_object_data` function before any validation takes place, with the potential of failing with a hard error. Similar to the "related objects not list" case explicitly validate the elements general type, and raise a normal validation error if it isn't a dictionary. The word "dictionary" is used here, since it is python terminology, and is close enough to yaml's "mapping". While json calls them "objects", their key-value syntax should make it obvious what "dictionary" means here.
This commit is contained in:
parent
78223cea03
commit
1245a9f99d
@ -1074,6 +1074,43 @@ console-ports: {value}
|
|||||||
self.assertHttpStatus(response, 200)
|
self.assertHttpStatus(response, 200)
|
||||||
self.assertContains(response, "Record 1 console-ports: Must be a list.")
|
self.assertContains(response, "Record 1 console-ports: Must be a list.")
|
||||||
|
|
||||||
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
|
||||||
|
def test_import_nodict(self):
|
||||||
|
# Add all required permissions to the test user
|
||||||
|
self.add_permissions(
|
||||||
|
'dcim.view_devicetype',
|
||||||
|
'dcim.add_devicetype',
|
||||||
|
'dcim.add_consoleporttemplate',
|
||||||
|
'dcim.add_consoleserverporttemplate',
|
||||||
|
'dcim.add_powerporttemplate',
|
||||||
|
'dcim.add_poweroutlettemplate',
|
||||||
|
'dcim.add_interfacetemplate',
|
||||||
|
'dcim.add_frontporttemplate',
|
||||||
|
'dcim.add_rearporttemplate',
|
||||||
|
'dcim.add_modulebaytemplate',
|
||||||
|
'dcim.add_devicebaytemplate',
|
||||||
|
'dcim.add_inventoryitemtemplate',
|
||||||
|
)
|
||||||
|
|
||||||
|
for value in ('', 'null', '3', '"My console port"', '["My other console port"]'):
|
||||||
|
with self.subTest(value=value):
|
||||||
|
import_data = f'''
|
||||||
|
manufacturer: Manufacturer 1
|
||||||
|
model: TEST-4000
|
||||||
|
slug: test-4000
|
||||||
|
u_height: 1
|
||||||
|
console-ports:
|
||||||
|
- {value}
|
||||||
|
'''
|
||||||
|
form_data = {
|
||||||
|
'data': import_data,
|
||||||
|
'format': 'yaml'
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.client.post(reverse('dcim:devicetype_bulk_import'), data=form_data, follow=True)
|
||||||
|
self.assertHttpStatus(response, 200)
|
||||||
|
self.assertContains(response, "Record 1 console-ports[1]: Must be a dictionary.")
|
||||||
|
|
||||||
def test_export_objects(self):
|
def test_export_objects(self):
|
||||||
url = reverse('dcim:devicetype_list')
|
url = reverse('dcim:devicetype_list')
|
||||||
self.add_permissions('dcim.view_devicetype')
|
self.add_permissions('dcim.view_devicetype')
|
||||||
|
|||||||
@ -392,6 +392,14 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView):
|
|||||||
|
|
||||||
related_obj_pks = []
|
related_obj_pks = []
|
||||||
for i, rel_obj_data in enumerate(related_objects, start=1):
|
for i, rel_obj_data in enumerate(related_objects, start=1):
|
||||||
|
if not isinstance(rel_obj_data, dict):
|
||||||
|
raise ValidationError(
|
||||||
|
self._compile_form_errors(
|
||||||
|
{f'{field_name}[{i}]': [_("Must be a dictionary.")]},
|
||||||
|
index=parent_idx,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
rel_obj_data = self.prep_related_object_data(obj, rel_obj_data)
|
rel_obj_data = self.prep_related_object_data(obj, rel_obj_data)
|
||||||
f = related_object_form(rel_obj_data)
|
f = related_object_form(rel_obj_data)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user