mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Convert device components to use NaturalOrderingField
This commit is contained in:
parent
b271fd32bd
commit
12d09e2274
140
netbox/dcim/migrations/0093_device_component_ordering.py
Normal file
140
netbox/dcim/migrations/0093_device_component_ordering.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
import utilities.fields
|
||||||
|
import utilities.ordering
|
||||||
|
|
||||||
|
|
||||||
|
def _update_model_names(model):
|
||||||
|
# Update each unique field value in bulk
|
||||||
|
for name in model.objects.values_list('name', flat=True).order_by('name').distinct():
|
||||||
|
model.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_consoleports(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'ConsolePort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_consoleserverports(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'ConsoleServerPort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_powerports(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'PowerPort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_poweroutlets(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'PowerPort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_frontports(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'FrontPort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_rearports(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'RearPort'))
|
||||||
|
|
||||||
|
|
||||||
|
def naturalize_devicebays(apps, schema_editor):
|
||||||
|
_update_model_names(apps.get_model('dcim', 'DeviceBay'))
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0092_fix_rack_outer_unit'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='consoleport',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='consoleserverport',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='devicebay',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='frontport',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='inventoryitem',
|
||||||
|
options={'ordering': ('device__id', 'parent__id', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='poweroutlet',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='powerport',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='rearport',
|
||||||
|
options={'ordering': ('device', '_name')},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='consoleport',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='consoleserverport',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='devicebay',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='frontport',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='inventoryitem',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='poweroutlet',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='powerport',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='rearport',
|
||||||
|
name='_name',
|
||||||
|
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_consoleports
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_consoleserverports
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_powerports
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_poweroutlets
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_frontports
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_rearports
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=naturalize_devicebays
|
||||||
|
),
|
||||||
|
]
|
@ -12,7 +12,7 @@ from dcim.exceptions import LoopDetected
|
|||||||
from dcim.fields import MACAddressField
|
from dcim.fields import MACAddressField
|
||||||
from dcim.managers import InterfaceManager
|
from dcim.managers import InterfaceManager
|
||||||
from extras.models import ObjectChange, TaggedItem
|
from extras.models import ObjectChange, TaggedItem
|
||||||
from utilities.managers import NaturalOrderingManager
|
from utilities.fields import NaturalOrderingField
|
||||||
from utilities.utils import serialize_object
|
from utilities.utils import serialize_object
|
||||||
from virtualization.choices import VMInterfaceTypeChoices
|
from virtualization.choices import VMInterfaceTypeChoices
|
||||||
|
|
||||||
@ -181,6 +181,11 @@ class ConsolePort(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=50
|
max_length=50
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -197,15 +202,13 @@ class ConsolePort(CableTermination, ComponentModel):
|
|||||||
choices=CONNECTION_STATUS_CHOICES,
|
choices=CONNECTION_STATUS_CHOICES,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'description']
|
csv_headers = ['device', 'name', 'type', 'description']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
unique_together = ['device', 'name']
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -238,6 +241,11 @@ class ConsoleServerPort(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=50
|
max_length=50
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -247,14 +255,13 @@ class ConsoleServerPort(CableTermination, ComponentModel):
|
|||||||
choices=CONNECTION_STATUS_CHOICES,
|
choices=CONNECTION_STATUS_CHOICES,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'description']
|
csv_headers = ['device', 'name', 'type', 'description']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -287,6 +294,11 @@ class PowerPort(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=50
|
max_length=50
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerPortTypeChoices,
|
choices=PowerPortTypeChoices,
|
||||||
@ -322,15 +334,13 @@ class PowerPort(CableTermination, ComponentModel):
|
|||||||
choices=CONNECTION_STATUS_CHOICES,
|
choices=CONNECTION_STATUS_CHOICES,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'maximum_draw', 'allocated_draw', 'description']
|
csv_headers = ['device', 'name', 'type', 'maximum_draw', 'allocated_draw', 'description']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
unique_together = ['device', 'name']
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -433,6 +443,11 @@ class PowerOutlet(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=50
|
max_length=50
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerOutletTypeChoices,
|
choices=PowerOutletTypeChoices,
|
||||||
@ -455,14 +470,13 @@ class PowerOutlet(CableTermination, ComponentModel):
|
|||||||
choices=CONNECTION_STATUS_CHOICES,
|
choices=CONNECTION_STATUS_CHOICES,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'power_port', 'feed_leg', 'description']
|
csv_headers = ['device', 'name', 'type', 'power_port', 'feed_leg', 'description']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -761,6 +775,11 @@ class FrontPort(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -774,20 +793,17 @@ class FrontPort(CableTermination, ComponentModel):
|
|||||||
default=1,
|
default=1,
|
||||||
validators=[MinValueValidator(1), MaxValueValidator(64)]
|
validators=[MinValueValidator(1), MaxValueValidator(64)]
|
||||||
)
|
)
|
||||||
|
|
||||||
is_path_endpoint = False
|
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'rear_port', 'rear_port_position', 'description']
|
csv_headers = ['device', 'name', 'type', 'rear_port', 'rear_port_position', 'description']
|
||||||
|
is_path_endpoint = False
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
unique_together = [
|
unique_together = (
|
||||||
['device', 'name'],
|
('device', 'name'),
|
||||||
['rear_port', 'rear_port_position'],
|
('rear_port', 'rear_port_position'),
|
||||||
]
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -831,6 +847,11 @@ class RearPort(CableTermination, ComponentModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -839,17 +860,14 @@ class RearPort(CableTermination, ComponentModel):
|
|||||||
default=1,
|
default=1,
|
||||||
validators=[MinValueValidator(1), MaxValueValidator(64)]
|
validators=[MinValueValidator(1), MaxValueValidator(64)]
|
||||||
)
|
)
|
||||||
|
|
||||||
is_path_endpoint = False
|
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'type', 'positions', 'description']
|
csv_headers = ['device', 'name', 'type', 'positions', 'description']
|
||||||
|
is_path_endpoint = False
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
unique_together = ['device', 'name']
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -881,6 +899,11 @@ class DeviceBay(ComponentModel):
|
|||||||
max_length=50,
|
max_length=50,
|
||||||
verbose_name='Name'
|
verbose_name='Name'
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
installed_device = models.OneToOneField(
|
installed_device = models.OneToOneField(
|
||||||
to='dcim.Device',
|
to='dcim.Device',
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
@ -888,15 +911,13 @@ class DeviceBay(ComponentModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = NaturalOrderingManager()
|
|
||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = ['device', 'name', 'installed_device', 'description']
|
csv_headers = ['device', 'name', 'installed_device', 'description']
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device', 'name']
|
ordering = ('device', '_name')
|
||||||
unique_together = ['device', 'name']
|
unique_together = ('device', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} - {}'.format(self.device.name, self.name)
|
return '{} - {}'.format(self.device.name, self.name)
|
||||||
@ -960,6 +981,11 @@ class InventoryItem(ComponentModel):
|
|||||||
max_length=50,
|
max_length=50,
|
||||||
verbose_name='Name'
|
verbose_name='Name'
|
||||||
)
|
)
|
||||||
|
_name = NaturalOrderingField(
|
||||||
|
target_field='name',
|
||||||
|
max_length=100,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
manufacturer = models.ForeignKey(
|
manufacturer = models.ForeignKey(
|
||||||
to='dcim.Manufacturer',
|
to='dcim.Manufacturer',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
@ -997,8 +1023,8 @@ class InventoryItem(ComponentModel):
|
|||||||
]
|
]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['device__id', 'parent__id', 'name']
|
ordering = ('device__id', 'parent__id', '_name')
|
||||||
unique_together = ['device', 'parent', 'name']
|
unique_together = ('device', 'parent', 'name')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
Loading…
Reference in New Issue
Block a user