Convert remaining DCIM models to use NaturalOrderingField

This commit is contained in:
Jeremy Stretch 2020-02-07 11:54:34 -05:00
parent 705c352885
commit 099c446f38
4 changed files with 100 additions and 26 deletions

View File

@ -0,0 +1,67 @@
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_sites(apps, schema_editor):
_update_model_names(apps.get_model('dcim', 'Site'))
def naturalize_racks(apps, schema_editor):
_update_model_names(apps.get_model('dcim', 'Rack'))
def naturalize_devices(apps, schema_editor):
_update_model_names(apps.get_model('dcim', 'Device'))
class Migration(migrations.Migration):
dependencies = [
('dcim', '0094_device_component_template_ordering'),
]
operations = [
migrations.AlterModelOptions(
name='device',
options={'ordering': ('_name', 'pk'), 'permissions': (('napalm_read', 'Read-only access to devices via NAPALM'), ('napalm_write', 'Read/write access to devices via NAPALM'))},
),
migrations.AlterModelOptions(
name='rack',
options={'ordering': ('site', 'group', '_name', 'pk')},
),
migrations.AlterModelOptions(
name='site',
options={'ordering': ('_name',)},
),
migrations.AddField(
model_name='device',
name='_name',
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
),
migrations.AddField(
model_name='rack',
name='_name',
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
),
migrations.AddField(
model_name='site',
name='_name',
field=utilities.fields.NaturalOrderingField('target_field', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize),
),
migrations.RunPython(
code=naturalize_sites
),
migrations.RunPython(
code=naturalize_racks
),
migrations.RunPython(
code=naturalize_devices
),
]

View File

@ -22,8 +22,7 @@ from dcim.choices import *
from dcim.constants import *
from dcim.fields import ASNField
from extras.models import ConfigContextModel, CustomFieldModel, TaggedItem
from utilities.fields import ColorField
from utilities.managers import NaturalOrderingManager
from utilities.fields import ColorField, NaturalOrderingField
from utilities.models import ChangeLoggedModel
from utilities.utils import foreground_color, to_meters
from .device_component_templates import (
@ -134,6 +133,11 @@ class Site(ChangeLoggedModel, CustomFieldModel):
max_length=50,
unique=True
)
_name = NaturalOrderingField(
target_field='name',
max_length=100,
blank=True
)
slug = models.SlugField(
unique=True
)
@ -215,8 +219,6 @@ class Site(ChangeLoggedModel, CustomFieldModel):
images = GenericRelation(
to='extras.ImageAttachment'
)
objects = NaturalOrderingManager()
tags = TaggableManager(through=TaggedItem)
csv_headers = [
@ -235,7 +237,7 @@ class Site(ChangeLoggedModel, CustomFieldModel):
}
class Meta:
ordering = ['name']
ordering = ('_name',)
def __str__(self):
return self.name
@ -516,6 +518,11 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin):
name = models.CharField(
max_length=50
)
_name = NaturalOrderingField(
target_field='name',
max_length=100,
blank=True
)
facility_id = models.CharField(
max_length=50,
blank=True,
@ -612,8 +619,6 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin):
images = GenericRelation(
to='extras.ImageAttachment'
)
objects = NaturalOrderingManager()
tags = TaggableManager(through=TaggedItem)
csv_headers = [
@ -634,12 +639,12 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin):
}
class Meta:
ordering = ('site', 'group', 'name', 'pk') # (site, group, name) may be non-unique
unique_together = [
ordering = ('site', 'group', '_name', 'pk') # (site, group, name) may be non-unique
unique_together = (
# Name and facility_id must be unique *only* within a RackGroup
['group', 'name'],
['group', 'facility_id'],
]
('group', 'name'),
('group', 'facility_id'),
)
def __str__(self):
return self.display_name or super().__str__()
@ -1313,6 +1318,11 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
blank=True,
null=True
)
_name = NaturalOrderingField(
target_field='name',
max_length=100,
blank=True
)
serial = models.CharField(
max_length=50,
blank=True,
@ -1407,8 +1417,6 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
images = GenericRelation(
to='extras.ImageAttachment'
)
objects = NaturalOrderingManager()
tags = TaggableManager(through=TaggedItem)
csv_headers = [
@ -1430,12 +1438,12 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
}
class Meta:
ordering = ('name', 'pk') # Name may be NULL
unique_together = [
['site', 'tenant', 'name'], # See validate_unique below
['rack', 'position', 'face'],
['virtual_chassis', 'vc_position'],
]
ordering = ('_name', 'pk') # Name may be blank
unique_together = (
('site', 'tenant', 'name'), # See validate_unique below
('rack', 'position', 'face'),
('virtual_chassis', 'vc_position'),
)
permissions = (
('napalm_read', 'Read-only access to devices via NAPALM'),
('napalm_write', 'Read/write access to devices via NAPALM'),

View File

@ -229,7 +229,7 @@ class RegionTable(BaseTable):
class SiteTable(BaseTable):
pk = ToggleColumn()
name = tables.LinkColumn(order_by=('_nat1', '_nat2', '_nat3'))
name = tables.LinkColumn()
status = tables.TemplateColumn(template_code=STATUS_LABEL, verbose_name='Status')
region = tables.TemplateColumn(template_code=SITE_REGION_LINK)
tenant = tables.TemplateColumn(template_code=COL_TENANT)
@ -291,7 +291,7 @@ class RackRoleTable(BaseTable):
class RackTable(BaseTable):
pk = ToggleColumn()
name = tables.LinkColumn(order_by=('_nat1', '_nat2', '_nat3'))
name = tables.LinkColumn()
site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')])
group = tables.Column(accessor=Accessor('group.name'), verbose_name='Group')
tenant = tables.TemplateColumn(template_code=COL_TENANT)
@ -653,10 +653,7 @@ class PlatformTable(BaseTable):
class DeviceTable(BaseTable):
pk = ToggleColumn()
name = tables.TemplateColumn(
order_by=('_nat1', '_nat2', '_nat3'),
template_code=DEVICE_LINK
)
name = tables.TemplateColumn(template_code=DEVICE_LINK)
status = tables.TemplateColumn(template_code=STATUS_LABEL, verbose_name='Status')
tenant = tables.TemplateColumn(template_code=COL_TENANT)
site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')])

View File

@ -20,6 +20,8 @@ def naturalize(value, max_length=None, integer_places=8):
:param max_length: The maximum length of the returned string. Characters beyond this length will be stripped.
:param integer_places: The number of places to which each integer will be expanded. (Default: 8)
"""
if not value:
return ''
output = []
for segment in re.split(r'(\d+)', value):
if segment.isdigit():