Skip to content

Commit 89a90a8

Browse files
committed
Fixes #19827: Enforce uniqueness for device role names & slugs
1 parent 9c2cd66 commit 89a90a8

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
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

0 commit comments

Comments
 (0)