diff --git a/docs/release-notes/version-2.8.md b/docs/release-notes/version-2.8.md index 0b0539c02..da131857a 100644 --- a/docs/release-notes/version-2.8.md +++ b/docs/release-notes/version-2.8.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#4489](https://github.com/netbox-community/netbox/issues/4489) - Fix display of parent/child role on device type view +* [#4496](https://github.com/netbox-community/netbox/issues/4496) - Fix exception when validating certain models via REST API --- diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 04d125b21..9ac58dc3a 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -143,8 +143,7 @@ class RackSerializer(TaggitSerializer, CustomFieldModelSerializer): # Validate uniqueness of (group, facility_id) since we omitted the automatically-created validator from Meta. if data.get('facility_id', None): validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('group', 'facility_id')) - validator.set_context(self) - validator(data) + validator(data, self) # Enforce model validation super().validate(data) @@ -395,8 +394,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): # Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta. if data.get('rack') and data.get('position') and data.get('face'): validator = UniqueTogetherValidator(queryset=Device.objects.all(), fields=('rack', 'position', 'face')) - validator.set_context(self) - validator(data) + validator(data, self) # Enforce model validation super().validate(data) diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 26cf3d1c2..d45d972f8 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -582,6 +582,7 @@ class RackTest(APITestCase): data = { 'name': 'Test Rack 4', + 'facility_id': '1234', 'site': self.site1.pk, 'group': self.rackgroup1.pk, 'role': self.rackrole1.pk, @@ -1815,6 +1816,7 @@ class DeviceTest(APITestCase): self.site1 = Site.objects.create(name='Test Site 1', slug='test-site-1') self.site2 = Site.objects.create(name='Test Site 2', slug='test-site-2') + self.rack1 = Rack.objects.create(name='Test Rack 1', site=self.site1, u_height=48) manufacturer = Manufacturer.objects.create(name='Test Manufacturer 1', slug='test-manufacturer-1') self.devicetype1 = DeviceType.objects.create( manufacturer=manufacturer, model='Test Device Type 1', slug='test-device-type-1' @@ -1920,6 +1922,9 @@ class DeviceTest(APITestCase): 'device_role': self.devicerole1.pk, 'name': 'Test Device 4', 'site': self.site1.pk, + 'rack': self.rack1.pk, + 'face': DeviceFaceChoices.FACE_FRONT, + 'position': 1, 'cluster': self.cluster1.pk, } diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index 5abe4c585..4e596631d 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -90,8 +90,7 @@ class VLANGroupSerializer(ValidatedModelSerializer): if data.get('site', None): for field in ['name', 'slug']: validator = UniqueTogetherValidator(queryset=VLANGroup.objects.all(), fields=('site', field)) - validator.set_context(self) - validator(data) + validator(data, self) # Enforce model validation super().validate(data) @@ -122,8 +121,7 @@ class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer): if data.get('group', None): for field in ['vid', 'name']: validator = UniqueTogetherValidator(queryset=VLAN.objects.all(), fields=('group', field)) - validator.set_context(self) - validator(data) + validator(data, self) # Enforce model validation super().validate(data) diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index b38daa079..c20ef6158 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -785,6 +785,7 @@ class VLANGroupTest(APITestCase): super().setUp() + self.site1 = Site.objects.create(name='Test Site 1', slug='test-site-1') self.vlangroup1 = VLANGroup.objects.create(name='Test VLAN Group 1', slug='test-vlan-group-1') self.vlangroup2 = VLANGroup.objects.create(name='Test VLAN Group 2', slug='test-vlan-group-2') self.vlangroup3 = VLANGroup.objects.create(name='Test VLAN Group 3', slug='test-vlan-group-3') @@ -818,6 +819,7 @@ class VLANGroupTest(APITestCase): data = { 'name': 'Test VLAN Group 4', 'slug': 'test-vlan-group-4', + 'site': self.site1.pk, } url = reverse('ipam-api:vlangroup-list') @@ -886,10 +888,10 @@ class VLANTest(APITestCase): super().setUp() + self.group1 = VLANGroup.objects.create(name='Test VLAN Group 1', slug='test-vlan-group-1') self.vlan1 = VLAN.objects.create(vid=1, name='Test VLAN 1') self.vlan2 = VLAN.objects.create(vid=2, name='Test VLAN 2') self.vlan3 = VLAN.objects.create(vid=3, name='Test VLAN 3') - self.prefix1 = Prefix.objects.create(prefix=IPNetwork('192.168.1.0/24')) def test_get_vlan(self): @@ -921,6 +923,7 @@ class VLANTest(APITestCase): data = { 'vid': 4, 'name': 'Test VLAN 4', + 'group': self.group1.pk, } url = reverse('ipam-api:vlan-list')