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>
This commit is contained in:
Brian Tiemann 2026-08-14 11:39:19 -04:00
parent f65c72da9c
commit 6cfda2b49c
4 changed files with 13 additions and 3 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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']

View File

@ -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')