mirror of
https://github.com/netbox-community/netbox.git
synced 2025-09-06 14:23:36 -06:00
Add prep_related_object_list hook
Related objects are saved in the same order as they are defined in the input by the user. So related objects with a dependency on another need to be saved after the related object they depend on. Which means that when required, the order needs to be changed. The related object lists are not part of the actual form, and the individual related-object forms only cover the elements themselves. So while the re-order should be done at the form-level during the clean- step, there is no form covering the lists to use for that. Plus should all errors be reported with their original location/index and not with the fixed/resorted one, because these are not useful and even confusing for the user. So the sorting should be done as late as possible, ideally just before the save. This adds a new `prep_related_object_list` hook, which gets passed each list of related objects. This should only be used for modifications to the list (aka order). Any changes to the individual objects should still be done using the existing `prep_related_object_data` hook. The passed list is not the plain list, but an enumerated variant. This is needed to preserve the original index of the elements independently from the actual (possibly changed) order the list, so any later detected errors (for example by the elements form validation) can accurately be reported back to the user.
This commit is contained in:
parent
18480668e0
commit
fa7b4d8978
@ -328,6 +328,13 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView):
|
|||||||
def get_required_permission(self):
|
def get_required_permission(self):
|
||||||
return get_permission_for_model(self.queryset.model, 'add')
|
return get_permission_for_model(self.queryset.model, 'add')
|
||||||
|
|
||||||
|
def prep_related_object_list(self, field_name, enumerated_list):
|
||||||
|
"""
|
||||||
|
Hook to modify the enumerated list of related objects before it's passed to the related object form (for
|
||||||
|
example, to change the order).
|
||||||
|
"""
|
||||||
|
pass # TODO keep in-place only, or return modified list?
|
||||||
|
|
||||||
def prep_related_object_data(self, parent, data):
|
def prep_related_object_data(self, parent, data):
|
||||||
"""
|
"""
|
||||||
Hook to modify the data for related objects before it's passed to the related object form (for example, to
|
Hook to modify the data for related objects before it's passed to the related object form (for example, to
|
||||||
@ -369,6 +376,13 @@ class BulkImportView(GetReturnURLMixin, BaseMultiObjectView):
|
|||||||
raise AbortTransaction()
|
raise AbortTransaction()
|
||||||
related_objects = list(enumerate(related_objects))
|
related_objects = list(enumerate(related_objects))
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.prep_related_object_list(field_name, related_objects)
|
||||||
|
except ValidationError as e:
|
||||||
|
for message in e.messages:
|
||||||
|
import_form.add_error(None, f"{field_name}: {message}")
|
||||||
|
raise AbortTransaction()
|
||||||
|
|
||||||
related_obj_pks = []
|
related_obj_pks = []
|
||||||
for i, rel_obj_data in related_objects:
|
for i, rel_obj_data in related_objects:
|
||||||
if not isinstance(rel_obj_data, dict): # TODO isinstance(MutableMapping)?
|
if not isinstance(rel_obj_data, dict): # TODO isinstance(MutableMapping)?
|
||||||
|
Loading…
Reference in New Issue
Block a user