Просмотр исходного кода

Convert device components to use NaturalOrderingField

Jeremy Stretch 6 лет назад
Родитель
Сommit
12d09e2274
2 измененных файлов с 202 добавлено и 36 удалено
  1. 140 0
      netbox/dcim/migrations/0093_device_component_ordering.py
  2. 62 36
      netbox/dcim/models/device_components.py

+ 140 - 0
netbox/dcim/migrations/0093_device_component_ordering.py

@@ -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
+        ),
+    ]

+ 62 - 36
netbox/dcim/models/device_components.py

@@ -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']
-        unique_together = ['device', 'name']
+        ordering = ('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']
-        unique_together = ['device', 'name']
+        ordering = ('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']
-        unique_together = [
-            ['device', 'name'],
-            ['rear_port', 'rear_port_position'],
-        ]
+        ordering = ('device', '_name')
+        unique_together = (
+            ('device', 'name'),
+            ('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']
-        unique_together = ['device', 'name']
+        ordering = ('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']
-        unique_together = ['device', 'name']
+        ordering = ('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']
-        unique_together = ['device', 'parent', 'name']
+        ordering = ('device__id', 'parent__id', '_name')
+        unique_together = ('device', 'parent', 'name')
 
 
     def __str__(self):
     def __str__(self):
         return self.name
         return self.name