mirror of
https://github.com/netbox-community/netbox.git
synced 2026-03-26 03:11:49 +01:00
Fix {module} placeholder resolution in module bay position field (#21752)
* Fix {module} placeholder resolution in module bay position field (#20467)
The {module} placeholder in ModuleBayTemplate's position field was not
being resolved when a module was installed, leaving the literal string
"{module}" in the position. This adds a resolve_position() method and
calls it in instantiate(), consistent with how resolve_name() and
resolve_label() already work.
Consolidates the shared resolution logic into _resolve_module_placeholder()
to eliminate duplication across resolve_name, resolve_label, and the new
resolve_position.
Fixes: #20467
* Move resolve_position() to ModuleBayTemplate
---------
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
committed by
GitHub
parent
981f31304d
commit
e76203238d
@@ -177,29 +177,19 @@ class ModularComponentTemplateModel(ComponentTemplateModel):
|
||||
modules.reverse()
|
||||
return modules
|
||||
|
||||
def resolve_name(self, module):
|
||||
if MODULE_TOKEN not in self.name:
|
||||
return self.name
|
||||
def _resolve_module_placeholder(self, value, module):
|
||||
if MODULE_TOKEN not in value or not module:
|
||||
return value
|
||||
modules = self._get_module_tree(module)
|
||||
for m in modules:
|
||||
value = value.replace(MODULE_TOKEN, m.module_bay.position, 1)
|
||||
return value
|
||||
|
||||
if module:
|
||||
modules = self._get_module_tree(module)
|
||||
name = self.name
|
||||
for module in modules:
|
||||
name = name.replace(MODULE_TOKEN, module.module_bay.position, 1)
|
||||
return name
|
||||
return self.name
|
||||
def resolve_name(self, module):
|
||||
return self._resolve_module_placeholder(self.name, module)
|
||||
|
||||
def resolve_label(self, module):
|
||||
if MODULE_TOKEN not in self.label:
|
||||
return self.label
|
||||
|
||||
if module:
|
||||
modules = self._get_module_tree(module)
|
||||
label = self.label
|
||||
for module in modules:
|
||||
label = label.replace(MODULE_TOKEN, module.module_bay.position, 1)
|
||||
return label
|
||||
return self.label
|
||||
return self._resolve_module_placeholder(self.label, module)
|
||||
|
||||
|
||||
class ConsolePortTemplate(ModularComponentTemplateModel):
|
||||
@@ -729,11 +719,14 @@ class ModuleBayTemplate(ModularComponentTemplateModel):
|
||||
verbose_name = _('module bay template')
|
||||
verbose_name_plural = _('module bay templates')
|
||||
|
||||
def resolve_position(self, module):
|
||||
return self._resolve_module_placeholder(self.position, module)
|
||||
|
||||
def instantiate(self, **kwargs):
|
||||
return self.component_model(
|
||||
name=self.resolve_name(kwargs.get('module')),
|
||||
label=self.resolve_label(kwargs.get('module')),
|
||||
position=self.position,
|
||||
position=self.resolve_position(kwargs.get('module')),
|
||||
**kwargs
|
||||
)
|
||||
instantiate.do_not_call_in_templates = True
|
||||
|
||||
@@ -849,6 +849,50 @@ class ModuleBayTestCase(TestCase):
|
||||
nested_bay = module.modulebays.get(name='SFP A-21')
|
||||
self.assertEqual(nested_bay.label, 'A-21')
|
||||
|
||||
@tag('regression') # #20467
|
||||
def test_nested_module_bay_position_resolution(self):
|
||||
"""Test that {module} in a module bay template's position field is resolved when the module is installed."""
|
||||
manufacturer = Manufacturer.objects.first()
|
||||
site = Site.objects.first()
|
||||
device_role = DeviceRole.objects.first()
|
||||
|
||||
device_type = DeviceType.objects.create(
|
||||
manufacturer=manufacturer,
|
||||
model='Device with Position Test',
|
||||
slug='device-with-position-test'
|
||||
)
|
||||
ModuleBayTemplate.objects.create(
|
||||
device_type=device_type,
|
||||
name='Slot 1',
|
||||
position='1'
|
||||
)
|
||||
|
||||
module_type = ModuleType.objects.create(
|
||||
manufacturer=manufacturer,
|
||||
model='Module with Position Placeholder'
|
||||
)
|
||||
ModuleBayTemplate.objects.create(
|
||||
module_type=module_type,
|
||||
name='Sub-bay {module}-1',
|
||||
position='{module}-1'
|
||||
)
|
||||
|
||||
device = Device.objects.create(
|
||||
name='Position Test Device',
|
||||
device_type=device_type,
|
||||
role=device_role,
|
||||
site=site
|
||||
)
|
||||
module_bay = device.modulebays.get(name='Slot 1')
|
||||
module = Module.objects.create(
|
||||
device=device,
|
||||
module_bay=module_bay,
|
||||
module_type=module_type
|
||||
)
|
||||
|
||||
nested_bay = module.modulebays.get(name='Sub-bay 1-1')
|
||||
self.assertEqual(nested_bay.position, '1-1')
|
||||
|
||||
@tag('regression') # #20912
|
||||
def test_module_bay_parent_cleared_when_module_removed(self):
|
||||
"""Test that the parent field is properly cleared when a module bay's module assignment is removed"""
|
||||
|
||||
Reference in New Issue
Block a user