Convert device components to use NaturalOrderingField

This commit is contained in:
Jeremy Stretch 2020-02-07 11:36:58 -05:00
parent b271fd32bd
commit 12d09e2274
2 changed files with 202 additions and 36 deletions

View 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
),
]

View File

@ -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