12118 fix instantiting device template with parent-child relations

This commit is contained in:
Arthur 2023-04-04 09:46:16 -07:00
parent b032742418
commit b4622bfd1a
2 changed files with 22 additions and 5 deletions

View File

@ -638,13 +638,20 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel):
)
def instantiate(self, **kwargs):
parent = InventoryItem.objects.get(name=self.parent.name, **kwargs) if self.parent else None
# if instance_map this means this is instantiating from a template, so need to map
# parent pointers to their previously instanced object and not the template one
instance_map = kwargs.pop('instance_map', None)
if self.parent and instance_map and self.parent.name in instance_map:
parent = instance_map[self.parent.name]
else:
parent = InventoryItem.objects.get(name=self.parent.name, **kwargs) if self.parent else None
if self.component:
model = self.component.component_model
component = model.objects.get(name=self.component.name, **kwargs)
else:
component = None
return self.component_model(
obj = self.component_model(
parent=parent,
name=self.name,
label=self.label,
@ -654,3 +661,7 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel):
part_id=self.part_id,
**kwargs
)
if instance_map is not None:
instance_map[self.name] = obj
return obj

View File

@ -766,15 +766,21 @@ class Device(PrimaryModel, ConfigContextModel):
'vc_position': "A device assigned to a virtual chassis must have its position defined."
})
def _instantiate_components(self, queryset, bulk_create=True):
def _instantiate_components(self, queryset, bulk_create=True, from_template=False):
"""
Instantiate components for the device from the specified component templates.
Args:
bulk_create: If True, bulk_create() will be called to create all components in a single query
(default). Otherwise, save() will be called on each instance individually.
from_template: If True will create an instance map to map parent-child template ids
to the newly created instances.
"""
components = [obj.instantiate(device=self) for obj in queryset]
instance_map = None
if from_template:
instance_map = {}
components = [obj.instantiate(device=self, instance_map=instance_map) for obj in queryset]
if components and bulk_create:
model = components[0]._meta.model
model.objects.bulk_create(components)
@ -816,7 +822,7 @@ class Device(PrimaryModel, ConfigContextModel):
self._instantiate_components(self.device_type.modulebaytemplates.all())
self._instantiate_components(self.device_type.devicebaytemplates.all())
# Disable bulk_create to accommodate MPTT
self._instantiate_components(self.device_type.inventoryitemtemplates.all(), bulk_create=False)
self._instantiate_components(self.device_type.inventoryitemtemplates.all(), bulk_create=False, from_template=True)
# Update Site and Rack assignment for any child Devices
devices = Device.objects.filter(parent_bay__device=self)