fix: bind rack width form to device edit route
This commit is contained in:
@@ -36,7 +36,7 @@ Release-Tag oder ein bestimmter Commit verwendet werden:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
/opt/netbox/venv/bin/pip install --upgrade --force-reinstall \
|
/opt/netbox/venv/bin/pip install --upgrade --force-reinstall \
|
||||||
"git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.8.1"
|
"git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.8.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternativ kann hinter dem `@` die vollständige Commit-ID stehen.
|
Alternativ kann hinter dem `@` die vollständige Commit-ID stehen.
|
||||||
@@ -136,7 +136,7 @@ empfohlen.
|
|||||||
### Mehrere Geräte nebeneinander in derselben HE
|
### Mehrere Geräte nebeneinander in derselben HE
|
||||||
|
|
||||||
Auf der normalen **Bearbeitungsseite eines Geräts** stehen direkt nach
|
Auf der normalen **Bearbeitungsseite eines Geräts** stehen direkt nach
|
||||||
**Rackseite** zwei neue optionale Felder zur Verfügung. Dafür wird kein
|
**Position** zwei neue optionale Felder zur Verfügung. Dafür wird kein
|
||||||
separates Plugin-Menü benötigt:
|
separates Plugin-Menü benötigt:
|
||||||
|
|
||||||
- **Rackbreite**: volle, halbe, Drittel- oder Viertelbreite;
|
- **Rackbreite**: volle, halbe, Drittel- oder Viertelbreite;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from netbox.plugins import PluginConfig, get_plugin_config
|
from netbox.plugins import PluginConfig, get_plugin_config
|
||||||
|
|
||||||
__version__ = "0.8.1"
|
__version__ = "0.8.2"
|
||||||
|
|
||||||
|
|
||||||
class NetBoxUtilitiesConfig(PluginConfig):
|
class NetBoxUtilitiesConfig(PluginConfig):
|
||||||
|
|||||||
@@ -307,6 +307,7 @@ def _install_device_validation():
|
|||||||
|
|
||||||
def _install_device_form():
|
def _install_device_form():
|
||||||
from dcim.views import DeviceEditView
|
from dcim.views import DeviceEditView
|
||||||
|
from netbox.registry import registry
|
||||||
|
|
||||||
if getattr(DeviceEditView, "_netbox_utilities_rack_width_installed", False):
|
if getattr(DeviceEditView, "_netbox_utilities_rack_width_installed", False):
|
||||||
return
|
return
|
||||||
@@ -341,7 +342,7 @@ def _install_device_form():
|
|||||||
if name in {"utilities_rack_width", "utilities_horizontal_position"}:
|
if name in {"utilities_rack_width", "utilities_horizontal_position"}:
|
||||||
continue
|
continue
|
||||||
reordered[name] = field
|
reordered[name] = field
|
||||||
if name == "face":
|
if name == "position":
|
||||||
reordered["utilities_rack_width"] = self.fields["utilities_rack_width"]
|
reordered["utilities_rack_width"] = self.fields["utilities_rack_width"]
|
||||||
reordered["utilities_horizontal_position"] = self.fields["utilities_horizontal_position"]
|
reordered["utilities_horizontal_position"] = self.fields["utilities_horizontal_position"]
|
||||||
self.fields = reordered
|
self.fields = reordered
|
||||||
@@ -379,6 +380,20 @@ def _install_device_form():
|
|||||||
|
|
||||||
RackWidthDeviceForm.__module__ = __name__
|
RackWidthDeviceForm.__module__ = __name__
|
||||||
RackWidthDeviceForm.__qualname__ = "RackWidthDeviceForm"
|
RackWidthDeviceForm.__qualname__ = "RackWidthDeviceForm"
|
||||||
|
|
||||||
|
class RackWidthDeviceEditView(DeviceEditView):
|
||||||
|
form = RackWidthDeviceForm
|
||||||
|
|
||||||
|
RackWidthDeviceEditView.__module__ = __name__
|
||||||
|
RackWidthDeviceEditView.__qualname__ = "RackWidthDeviceEditView"
|
||||||
|
|
||||||
|
for view_config in registry["views"]["dcim"]["device"]:
|
||||||
|
if view_config["name"] == "edit":
|
||||||
|
view_config["view"] = RackWidthDeviceEditView
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Die NetBox-Gerätebearbeitung ist nicht in der View-Registry registriert.")
|
||||||
|
|
||||||
DeviceEditView.form = RackWidthDeviceForm
|
DeviceEditView.form = RackWidthDeviceForm
|
||||||
DeviceEditView._netbox_utilities_rack_width_installed = True
|
DeviceEditView._netbox_utilities_rack_width_installed = True
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ from types import SimpleNamespace
|
|||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.template.loader import render_to_string
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
|
from django.urls import resolve, reverse
|
||||||
|
|
||||||
from netbox_utilities.rack_width import (
|
from netbox_utilities.rack_width import (
|
||||||
_cleanup_unracked_placement,
|
_cleanup_unracked_placement,
|
||||||
@@ -19,11 +21,45 @@ from netbox_utilities.rack_width import (
|
|||||||
|
|
||||||
class RackWidthTest(SimpleTestCase):
|
class RackWidthTest(SimpleTestCase):
|
||||||
def test_device_edit_view_uses_explicit_rack_width_form(self):
|
def test_device_edit_view_uses_explicit_rack_width_form(self):
|
||||||
from dcim.views import DeviceEditView
|
from netbox.registry import registry
|
||||||
|
|
||||||
self.assertEqual(DeviceEditView.form.__name__, "RackWidthDeviceForm")
|
edit_view = next(view["view"] for view in registry["views"]["dcim"]["device"] if view["name"] == "edit")
|
||||||
self.assertIn("utilities_rack_width", DeviceEditView.form.base_fields)
|
|
||||||
self.assertIn("utilities_horizontal_position", DeviceEditView.form.base_fields)
|
self.assertEqual(edit_view.__name__, "RackWidthDeviceEditView")
|
||||||
|
self.assertEqual(edit_view.form.__name__, "RackWidthDeviceForm")
|
||||||
|
self.assertIn("utilities_rack_width", edit_view.form.base_fields)
|
||||||
|
self.assertIn("utilities_horizontal_position", edit_view.form.base_fields)
|
||||||
|
|
||||||
|
def test_resolved_device_edit_page_renders_rack_width_fields(self):
|
||||||
|
from dcim.models import Device
|
||||||
|
|
||||||
|
object_type = SimpleNamespace(pk=1, model_class=lambda: Device)
|
||||||
|
with (
|
||||||
|
patch("core.models.ObjectType.objects.get_for_model", return_value=object_type),
|
||||||
|
patch(
|
||||||
|
"django.contrib.contenttypes.models.ContentType.objects.get_for_model",
|
||||||
|
return_value=object_type,
|
||||||
|
),
|
||||||
|
patch("extras.models.CustomField.objects.get_for_model", return_value=[]),
|
||||||
|
patch(
|
||||||
|
"netbox_utilities.runtime._get_database_settings",
|
||||||
|
return_value={"tenant_required": True},
|
||||||
|
),
|
||||||
|
):
|
||||||
|
url = reverse("dcim:device_edit", kwargs={"pk": 1})
|
||||||
|
view_class = resolve(url).func.view_class
|
||||||
|
form = view_class.form()
|
||||||
|
html = render_to_string("htmx/form.html", {"form": form})
|
||||||
|
|
||||||
|
width = 'name="utilities_rack_width"'
|
||||||
|
horizontal_position = 'name="utilities_horizontal_position"'
|
||||||
|
self.assertIn(width, html)
|
||||||
|
self.assertIn(horizontal_position, html)
|
||||||
|
field_names = list(form.fields)
|
||||||
|
self.assertEqual(
|
||||||
|
field_names[field_names.index("position") : field_names.index("position") + 4],
|
||||||
|
["position", "utilities_rack_width", "utilities_horizontal_position", "face"],
|
||||||
|
)
|
||||||
|
|
||||||
def test_normalizes_full_width_to_first_position(self):
|
def test_normalizes_full_width_to_first_position(self):
|
||||||
self.assertEqual(normalize_width_position(1, 4), (1, 1))
|
self.assertEqual(normalize_width_position(1, 4), (1, 1))
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "netbox-utilities"
|
name = "netbox-utilities"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
description = "Navigation, tenant utilities, partial-width rack devices, bulk uploads, and rack reordering for NetBox 4.6"
|
description = "Navigation, tenant utilities, partial-width rack devices, bulk uploads, and rack reordering for NetBox 4.6"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|||||||
Reference in New Issue
Block a user