From c2d0cfdfc07cbbadc751d14c436c302e99027db7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 18 Nov 2021 09:27:45 -0500 Subject: [PATCH] Fixes #7864: power_port can be null when creating power outlets --- docs/release-notes/version-3.0.md | 1 + netbox/dcim/api/serializers.py | 6 ++++-- netbox/dcim/tests/test_api.py | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.0.md b/docs/release-notes/version-3.0.md index a8a074d3f..f73d43c9e 100644 --- a/docs/release-notes/version-3.0.md +++ b/docs/release-notes/version-3.0.md @@ -20,6 +20,7 @@ * [#7851](https://github.com/netbox-community/netbox/issues/7851) - Add missing cluster name filter for virtual machines * [#7857](https://github.com/netbox-community/netbox/issues/7857) - Fix ordering IP addresses by assignment status * [#7859](https://github.com/netbox-community/netbox/issues/7859) - Fix styling of form widgets under cable connection views +* [#7864](https://github.com/netbox-community/netbox/issues/7864) - `power_port` can be null when creating power outlets --- diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 8e2fa15af..0872cce6d 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -356,7 +356,8 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer): required=False ) power_port = NestedPowerPortTemplateSerializer( - required=False + required=False, + allow_null=True ) feed_leg = ChoiceField( choices=PowerOutletFeedLegChoices, @@ -585,7 +586,8 @@ class PowerOutletSerializer(PrimaryModelSerializer, CableTerminationSerializer, required=False ) power_port = NestedPowerPortSerializer( - required=False + required=False, + allow_null=True ) feed_leg = ChoiceField( choices=PowerOutletFeedLegChoices, diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 3fc48beed..181d659d2 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -584,6 +584,12 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase): manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' ) + power_port_templates = ( + PowerPortTemplate(device_type=devicetype, name='Power Port Template 1'), + PowerPortTemplate(device_type=devicetype, name='Power Port Template 2'), + ) + PowerPortTemplate.objects.bulk_create(power_port_templates) + power_outlet_templates = ( PowerOutletTemplate(device_type=devicetype, name='Power Outlet Template 1'), PowerOutletTemplate(device_type=devicetype, name='Power Outlet Template 2'), @@ -595,14 +601,17 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase): { 'device_type': devicetype.pk, 'name': 'Power Outlet Template 4', + 'power_port': power_port_templates[0].pk, }, { 'device_type': devicetype.pk, 'name': 'Power Outlet Template 5', + 'power_port': power_port_templates[1].pk, }, { 'device_type': devicetype.pk, 'name': 'Power Outlet Template 6', + 'power_port': None, }, ] @@ -1139,6 +1148,12 @@ class PowerOutletTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCa devicerole = DeviceRole.objects.create(name='Test Device Role 1', slug='test-device-role-1', color='ff0000') device = Device.objects.create(device_type=devicetype, device_role=devicerole, name='Device 1', site=site) + power_ports = ( + PowerPort(device=device, name='Power Port 1'), + PowerPort(device=device, name='Power Port 2'), + ) + PowerPort.objects.bulk_create(power_ports) + power_outlets = ( PowerOutlet(device=device, name='Power Outlet 1'), PowerOutlet(device=device, name='Power Outlet 2'), @@ -1150,14 +1165,17 @@ class PowerOutletTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCa { 'device': device.pk, 'name': 'Power Outlet 4', + 'power_port': power_ports[0].pk, }, { 'device': device.pk, 'name': 'Power Outlet 5', + 'power_port': power_ports[1].pk, }, { 'device': device.pk, 'name': 'Power Outlet 6', + 'power_port': None, }, ]