diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 0f3ff85ab..1abac4e12 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -1,4 +1,5 @@ from rest_framework import serializers +from rest_framework.validators import UniqueTogetherValidator from ipam.models import IPAddress from dcim.models import ( @@ -157,6 +158,21 @@ class WritableRackSerializer(serializers.ModelSerializer): 'id', 'name', 'facility_id', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height', 'desc_units', 'comments', ] + # Omit the UniqueTogetherValidator that would be automatically added to validate facility_id. This prevents + # facility_id from being interpreted as a required field. + validators = [ + UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('site', 'name')) + ] + + def validate(self, data): + + # Validate uniqueness of facility_id (if set) since we omitted the automatically-created validator from Meta. + if data.get('facility_id', None): + validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('site', 'facility_id')) + validator.set_context(self) + validator(data) + + return data # diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index d2140d0fa..93eeab25c 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -310,7 +310,7 @@ class RackTest(APITestCase): self.rackrole1 = RackRole.objects.create(name='Test Rack Role 1', slug='test-rack-role-1', color='ff0000') self.rackrole2 = RackRole.objects.create(name='Test Rack Role 2', slug='test-rack-role-2', color='00ff00') self.rack1 = Rack.objects.create( - site=self.site1, group=self.rackgroup1, role=self.rackrole1, name='Test Rack 1' + site=self.site1, group=self.rackgroup1, role=self.rackrole1, name='Test Rack 1', ) self.rack2 = Rack.objects.create( site=self.site1, group=self.rackgroup1, role=self.rackrole1, name='Test Rack 2'