diff --git a/README.md b/README.md index 33a07b1..1a2485a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Release-Tag oder ein bestimmter Commit verwendet werden: ```bash /opt/netbox/venv/bin/pip install --upgrade --force-reinstall \ - "git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.8.5" + "git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.8.6" ``` Alternativ kann hinter dem `@` die vollständige Commit-ID stehen. diff --git a/netbox_utilities/__init__.py b/netbox_utilities/__init__.py index 1f00a7a..418b146 100644 --- a/netbox_utilities/__init__.py +++ b/netbox_utilities/__init__.py @@ -1,6 +1,6 @@ from netbox.plugins import PluginConfig, get_plugin_config -__version__ = "0.8.5" +__version__ = "0.8.6" class NetBoxUtilitiesConfig(PluginConfig): diff --git a/netbox_utilities/rack_width.py b/netbox_utilities/rack_width.py index c6aacb2..deebfdb 100644 --- a/netbox_utilities/rack_width.py +++ b/netbox_utilities/rack_width.py @@ -6,6 +6,7 @@ from functools import wraps from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError +from django.db.models import Count, Q from django.db.models.signals import post_save, pre_save from .models import DeviceRackPlacement @@ -452,14 +453,8 @@ def _install_rack_svg(): @wraps(original_draw_face) def width_aware_draw_face(elevation, face, opposite=False): original_draw_face(elevation, face, opposite) - placements = DeviceRackPlacement.objects.filter( - device__rack=elevation.rack, - device__position__isnull=False, - ).select_related("device", "device__device_type", "device__role") - for placement in placements: - device = placement.device - if not (device.face == face or device.device_type.is_full_depth): - continue + for device in _partial_width_elevation_devices(elevation.rack, face): + placement = device.netbox_utilities_rack_placement height = decimal.Decimal(str(device.device_type.u_height)) coords = elevation._get_device_coords(device.position, height) width = elevation.unit_width / placement.width @@ -479,6 +474,28 @@ def _install_rack_svg(): RackElevationSVG._netbox_utilities_rack_width_installed = True +def _partial_width_elevation_devices(rack, face): + """Return the annotated Device instances expected by NetBox's SVG renderer.""" + from dcim.models import Device + + return ( + Device.objects.filter( + rack=rack, + position__gt=0, + device_type__u_height__gt=0, + netbox_utilities_rack_placement__isnull=False, + ) + .filter(Q(face=face) | Q(device_type__is_full_depth=True)) + .select_related( + "device_type", + "device_type__manufacturer", + "role", + "netbox_utilities_rack_placement", + ) + .annotate(devicebay_count=Count("devicebays")) + ) + + def _validate_before_save(sender, instance, raw=False, **kwargs): if not raw: using = kwargs.get("using") diff --git a/netbox_utilities/tests/test_rack_width.py b/netbox_utilities/tests/test_rack_width.py index dbf85c3..b972182 100644 --- a/netbox_utilities/tests/test_rack_width.py +++ b/netbox_utilities/tests/test_rack_width.py @@ -12,6 +12,7 @@ from django.urls import resolve, reverse from netbox_utilities.rack_width import ( _cleanup_unracked_placement, + _partial_width_elevation_devices, available_units_for_device, horizontal_interval, include_rack_width_in_fieldsets, @@ -24,6 +25,17 @@ from netbox_utilities.rack_width import ( class RackWidthTest(SimpleTestCase): + def test_partial_width_svg_devices_include_core_device_bay_annotation(self): + from dcim.choices import DeviceFaceChoices + from dcim.models import Rack + + devices = _partial_width_elevation_devices(Rack(pk=3), DeviceFaceChoices.FACE_FRONT) + + self.assertIn("devicebay_count", devices.query.annotations) + self.assertIn("netbox_utilities_rack_placement", devices.query.select_related) + self.assertIn("device_type", devices.query.select_related) + self.assertIn("manufacturer", devices.query.select_related["device_type"]) + def test_adds_rack_width_fields_to_existing_location_fieldset(self): from utilities.forms.rendering import FieldSet diff --git a/pyproject.toml b/pyproject.toml index da65daf..f5f3aea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "netbox-utilities" -version = "0.8.5" +version = "0.8.6" description = "Navigation, tenant utilities, partial-width rack devices, bulk uploads, and rack reordering for NetBox 4.6" readme = "README.md" requires-python = ">=3.12"