Explorar o código

Fixes #19827: Enforce uniqueness for device role names & slugs (#19859)

Jeremy Stretch hai 7 meses
pai
achega
f13d028c98

+ 44 - 0
netbox/dcim/migrations/0208_devicerole_uniqueness.py

@@ -0,0 +1,44 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0207_remove_redundant_indexes'),
+        ('extras', '0129_fix_script_paths'),
+    ]
+
+    operations = [
+        migrations.AddConstraint(
+            model_name='devicerole',
+            constraint=models.UniqueConstraint(
+                fields=('parent', 'name'),
+                name='dcim_devicerole_parent_name'
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name='devicerole',
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('name',),
+                name='dcim_devicerole_name',
+                violation_error_message='A top-level device role with this name already exists.'
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name='devicerole',
+            constraint=models.UniqueConstraint(
+                fields=('parent', 'slug'),
+                name='dcim_devicerole_parent_slug'
+            ),
+        ),
+        migrations.AddConstraint(
+            model_name='devicerole',
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('slug',),
+                name='dcim_devicerole_slug',
+                violation_error_message='A top-level device role with this slug already exists.'
+            ),
+        ),
+    ]

+ 22 - 0
netbox/dcim/models/devices.py

@@ -398,6 +398,28 @@ class DeviceRole(NestedGroupModel):
 
     class Meta:
         ordering = ('name',)
+        constraints = (
+            models.UniqueConstraint(
+                fields=('parent', 'name'),
+                name='%(app_label)s_%(class)s_parent_name'
+            ),
+            models.UniqueConstraint(
+                fields=('name',),
+                name='%(app_label)s_%(class)s_name',
+                condition=Q(parent__isnull=True),
+                violation_error_message=_("A top-level device role with this name already exists.")
+            ),
+            models.UniqueConstraint(
+                fields=('parent', 'slug'),
+                name='%(app_label)s_%(class)s_parent_slug'
+            ),
+            models.UniqueConstraint(
+                fields=('slug',),
+                name='%(app_label)s_%(class)s_slug',
+                condition=Q(parent__isnull=True),
+                violation_error_message=_("A top-level device role with this slug already exists.")
+            ),
+        )
         verbose_name = _('device role')
         verbose_name_plural = _('device roles')
 

+ 3 - 3
netbox/dcim/tests/test_views.py

@@ -1804,9 +1804,9 @@ class DeviceRoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
 
         cls.csv_data = (
             "name,slug,color",
-            "Device Role 4,device-role-4,ff0000",
-            "Device Role 5,device-role-5,00ff00",
-            "Device Role 6,device-role-6,0000ff",
+            "Device Role 6,device-role-6,ff0000",
+            "Device Role 7,device-role-7,00ff00",
+            "Device Role 8,device-role-8,0000ff",
         )
 
         cls.csv_update_data = (