Skip to content

Commit f13d028

Browse files
Fixes #19827: Enforce uniqueness for device role names & slugs (#19859)
1 parent f5d32b1 commit f13d028

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from django.db import migrations, models
2+
3+
4+
class Migration(migrations.Migration):
5+
6+
dependencies = [
7+
('dcim', '0207_remove_redundant_indexes'),
8+
('extras', '0129_fix_script_paths'),
9+
]
10+
11+
operations = [
12+
migrations.AddConstraint(
13+
model_name='devicerole',
14+
constraint=models.UniqueConstraint(
15+
fields=('parent', 'name'),
16+
name='dcim_devicerole_parent_name'
17+
),
18+
),
19+
migrations.AddConstraint(
20+
model_name='devicerole',
21+
constraint=models.UniqueConstraint(
22+
condition=models.Q(('parent__isnull', True)),
23+
fields=('name',),
24+
name='dcim_devicerole_name',
25+
violation_error_message='A top-level device role with this name already exists.'
26+
),
27+
),
28+
migrations.AddConstraint(
29+
model_name='devicerole',
30+
constraint=models.UniqueConstraint(
31+
fields=('parent', 'slug'),
32+
name='dcim_devicerole_parent_slug'
33+
),
34+
),
35+
migrations.AddConstraint(
36+
model_name='devicerole',
37+
constraint=models.UniqueConstraint(
38+
condition=models.Q(('parent__isnull', True)),
39+
fields=('slug',),
40+
name='dcim_devicerole_slug',
41+
violation_error_message='A top-level device role with this slug already exists.'
42+
),
43+
),
44+
]

netbox/dcim/models/devices.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,28 @@ class DeviceRole(NestedGroupModel):
398398

399399
class Meta:
400400
ordering = ('name',)
401+
constraints = (
402+
models.UniqueConstraint(
403+
fields=('parent', 'name'),
404+
name='%(app_label)s_%(class)s_parent_name'
405+
),
406+
models.UniqueConstraint(
407+
fields=('name',),
408+
name='%(app_label)s_%(class)s_name',
409+
condition=Q(parent__isnull=True),
410+
violation_error_message=_("A top-level device role with this name already exists.")
411+
),
412+
models.UniqueConstraint(
413+
fields=('parent', 'slug'),
414+
name='%(app_label)s_%(class)s_parent_slug'
415+
),
416+
models.UniqueConstraint(
417+
fields=('slug',),
418+
name='%(app_label)s_%(class)s_slug',
419+
condition=Q(parent__isnull=True),
420+
violation_error_message=_("A top-level device role with this slug already exists.")
421+
),
422+
)
401423
verbose_name = _('device role')
402424
verbose_name_plural = _('device roles')
403425

netbox/dcim/tests/test_views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,9 +1804,9 @@ def setUpTestData(cls):
18041804

18051805
cls.csv_data = (
18061806
"name,slug,color",
1807-
"Device Role 4,device-role-4,ff0000",
1808-
"Device Role 5,device-role-5,00ff00",
1809-
"Device Role 6,device-role-6,0000ff",
1807+
"Device Role 6,device-role-6,ff0000",
1808+
"Device Role 7,device-role-7,00ff00",
1809+
"Device Role 8,device-role-8,0000ff",
18101810
)
18111811

18121812
cls.csv_update_data = (

0 commit comments

Comments
 (0)