Просмотр исходного кода

Address automated review: documentation clarifications for module_bay_types

- Document that ModuleType.to_yaml() exports module_bay_types by name but
  the field isn't currently importable back through it (no ModuleTypeImportForm
  field survived the CSV-import revert).
- modulebaytemplate.md's note covered only the device-type-parented import
  path; ModuleBayTemplateImportForm is registered for both DeviceTypeImportView
  and ModuleTypeImportView, scoping to whichever parent type's manufacturer
  applies. Reworded to cover both, and added the "rejected rather than
  resolved" clause for a name matching only some other manufacturer's type.
- Clarified clean_module_bay_types()'s docstring: the "never a cross-manufacturer
  collision" guarantee holds only because ModularComponentTemplateModel.clean()
  rejects a template with neither device_type nor module_type before this
  method's result would ever be saved.
- Fixed a test docstring overstating symmetry between its two comparison arms.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Brian Tiemann 1 неделя назад
Родитель
Сommit
6cfda2b49c

+ 1 - 1
docs/models/dcim/modulebaytemplate.md

@@ -4,4 +4,4 @@ A template for a module bay that will be created on all instantiations of the pa
 
 [Bay types](./modulebaytype.md) assigned to a module bay template are copied to each instantiated module bay, so constraints defined on the device type propagate automatically to all devices of that type.
 
-Bay types are importable and exportable as part of a device type's YAML definition (`module-bays[].module_bay_types`), referenced by name. A referenced name is resolved against bay types belonging to the device type's own manufacturer or with no manufacturer set (global); a name may match both, since a bay type's uniqueness is scoped to `(manufacturer, name)` rather than name alone, in which case the manufacturer-specific type takes precedence.
+Bay types are importable and exportable as part of a device type's or module type's YAML definition (`module-bays[].module_bay_types`), referenced by name. A referenced name is resolved against bay types belonging to the parent type's own manufacturer or with no manufacturer set (global); a name may match both, since a bay type's uniqueness is scoped to `(manufacturer, name)` rather than name alone, in which case the manufacturer-specific type takes precedence. A name matching only some other manufacturer's bay type is rejected rather than resolved to it.

+ 2 - 0
docs/models/dcim/moduletype.md

@@ -91,6 +91,8 @@ The assigned [profile](./moduletypeprofile.md) for the type of module. Profiles
 
 Zero or more [module bay types](./modulebaytype.md) that this module type is compatible with. When at least one bay type is set, the module type may only be installed into bays that share a common type. Leave empty to allow installation into any bay.
 
+Bay types are included, by name, in a module type's exported YAML definition, but are not currently importable back through it; re-importing an exported definition leaves this field unset.
+
 ### Attributes
 
 Depending on the module type's assigned [profile](./moduletypeprofile.md) (if any), one or more user-defined attributes may be available to configure.

+ 6 - 0
netbox/dcim/forms/object_import.py

@@ -263,6 +263,12 @@ class ModuleBayTemplateImportForm(forms.ModelForm):
         own manufacturer (narrowed by clean_device_type/clean_module_type above); the field's
         default name-based lookup resolves both matches into cleaned_data rather than picking
         one, since it has no way to know which is meant.
+
+        If neither device_type nor module_type resolved (so the queryset above was never
+        narrowed), a name could in principle collide across two unrelated manufacturers here
+        too. That's not reachable with valid data: ModularComponentTemplateModel.clean()
+        rejects a template with neither parent, so the form fails in _post_clean() before this
+        method's result would ever be saved.
         """
         module_bay_types = self.cleaned_data['module_bay_types']
 

+ 4 - 2
netbox/dcim/tests/test_views.py

@@ -1793,8 +1793,10 @@ module-bays:
         self.assertEqual(list(mb1.module_bay_types.values_list('name', flat=True)), ['SFP28'])
 
     def test_bulk_yaml_export_prefetches_module_bay_types_on_the_module_type_itself(self):
-        """Compares the same queryset with/without the prefetch, since row-count comparisons
-        would be swamped by other per-instance relations that legitimately scale with it."""
+        """Compares an unprefetched to_yaml() call per instance against export_yaml() (which
+        prefetches and issues no queries of its own beyond that), rather than a row-count
+        comparison, which other per-instance relations that legitimately scale with it would
+        swamp."""
         manufacturer = Manufacturer.objects.create(name='Export Query MT Manufacturer', slug='export-query-mt-mfr')
         bay_type = ModuleBayType.objects.create(name='Export Query MT SFP28', slug='export-query-mt-sfp28')