mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-29 11:56:25 -06:00
18981 Make Device Roles Hierarchical
This commit is contained in:
parent
fe7cc8cae9
commit
b5b1827893
@ -338,6 +338,8 @@ class InventoryItemTemplateType(ComponentTemplateType):
|
|||||||
pagination=True
|
pagination=True
|
||||||
)
|
)
|
||||||
class DeviceRoleType(OrganizationalObjectType):
|
class DeviceRoleType(OrganizationalObjectType):
|
||||||
|
parent: Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')] | None
|
||||||
|
children: List[Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')]]
|
||||||
color: str
|
color: str
|
||||||
config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None
|
config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None
|
||||||
|
|
||||||
|
56
netbox/dcim/migrations/0203_device_role_nested.py
Normal file
56
netbox/dcim/migrations/0203_device_role_nested.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# Generated by Django 5.1.7 on 2025-03-25 18:06
|
||||||
|
|
||||||
|
import django.db.models.manager
|
||||||
|
import mptt.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0202_location_comments_region_comments_sitegroup_comments'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelManagers(
|
||||||
|
name='devicerole',
|
||||||
|
managers=[
|
||||||
|
('_tree_manager', django.db.models.manager.Manager()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicerole',
|
||||||
|
name='level',
|
||||||
|
field=models.PositiveIntegerField(default=0, editable=False),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicerole',
|
||||||
|
name='lft',
|
||||||
|
field=models.PositiveIntegerField(default=0, editable=False),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicerole',
|
||||||
|
name='rght',
|
||||||
|
field=models.PositiveIntegerField(default=0, editable=False),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicerole',
|
||||||
|
name='tree_id',
|
||||||
|
field=models.PositiveIntegerField(db_index=True, default=0, editable=False),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicerole',
|
||||||
|
name='parent',
|
||||||
|
field=mptt.fields.TreeForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='children',
|
||||||
|
to='dcim.devicerole',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
22
netbox/dcim/migrations/0204_device_role_rebuild.py
Normal file
22
netbox/dcim/migrations/0204_device_role_rebuild.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
import mptt
|
||||||
|
import mptt.managers
|
||||||
|
|
||||||
|
|
||||||
|
def rebuild_mptt(apps, schema_editor):
|
||||||
|
manager = mptt.managers.TreeManager()
|
||||||
|
DeviceRole = apps.get_model('dcim', 'DeviceRole')
|
||||||
|
manager.model = DeviceRole
|
||||||
|
mptt.register(DeviceRole)
|
||||||
|
manager.contribute_to_class(DeviceRole, 'objects')
|
||||||
|
manager.rebuild()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0203_device_role_nested'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(code=rebuild_mptt, reverse_code=migrations.RunPython.noop),
|
||||||
|
]
|
@ -21,6 +21,7 @@ from dcim.constants import *
|
|||||||
from dcim.fields import MACAddressField
|
from dcim.fields import MACAddressField
|
||||||
from extras.models import ConfigContextModel, CustomField
|
from extras.models import ConfigContextModel, CustomField
|
||||||
from extras.querysets import ConfigContextModelQuerySet
|
from extras.querysets import ConfigContextModelQuerySet
|
||||||
|
from mptt.models import MPTTModel, TreeForeignKey
|
||||||
from netbox.choices import ColorChoices
|
from netbox.choices import ColorChoices
|
||||||
from netbox.config import ConfigItem
|
from netbox.config import ConfigItem
|
||||||
from netbox.models import OrganizationalModel, PrimaryModel
|
from netbox.models import OrganizationalModel, PrimaryModel
|
||||||
@ -468,12 +469,20 @@ class ModuleType(ImageAttachmentsMixin, PrimaryModel, WeightMixin):
|
|||||||
# Devices
|
# Devices
|
||||||
#
|
#
|
||||||
|
|
||||||
class DeviceRole(OrganizationalModel):
|
class DeviceRole(OrganizationalModel, MPTTModel):
|
||||||
"""
|
"""
|
||||||
Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a
|
Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a
|
||||||
color to be used when displaying rack elevations. The vm_role field determines whether the role is applicable to
|
color to be used when displaying rack elevations. The vm_role field determines whether the role is applicable to
|
||||||
virtual machines as well.
|
virtual machines as well.
|
||||||
"""
|
"""
|
||||||
|
parent = TreeForeignKey(
|
||||||
|
to='self',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='children',
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
db_index=True
|
||||||
|
)
|
||||||
color = ColorField(
|
color = ColorField(
|
||||||
verbose_name=_('color'),
|
verbose_name=_('color'),
|
||||||
default=ColorChoices.COLOR_GREY
|
default=ColorChoices.COLOR_GREY
|
||||||
|
Loading…
Reference in New Issue
Block a user