mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-29 20:06:25 -06:00
11279 add collation
This commit is contained in:
parent
33099499d6
commit
fb19be9cca
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.0.9 on 2024-11-12 22:21
|
||||
|
||||
from django.contrib.postgres.operations import CreateCollation
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0196_qinq_svlan'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
CreateCollation(
|
||||
"natural_sort",
|
||||
provider="icu",
|
||||
locale="und-u-ks-level2-kn-true",
|
||||
),
|
||||
]
|
306
netbox/dcim/migrations/0197_natural_sort.py
Normal file
306
netbox/dcim/migrations/0197_natural_sort.py
Normal file
@ -0,0 +1,306 @@
|
||||
# Generated by Django 5.0.9 on 2024-11-12 22:21
|
||||
|
||||
from django.contrib.postgres.operations import CreateCollation
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0196_qinq_svlan'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
CreateCollation(
|
||||
"natural_sort",
|
||||
provider="icu",
|
||||
locale="und-u-kn-true",
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='site',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='site',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='consoleport',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='consoleporttemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='consoleserverport',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='consoleserverporttemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='device',
|
||||
options={'ordering': ('name', 'pk')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='devicebay',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='devicebaytemplate',
|
||||
options={'ordering': ('device_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='frontport',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='frontporttemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='interfacetemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='inventoryitem',
|
||||
options={'ordering': ('device__id', 'parent__id', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='inventoryitemtemplate',
|
||||
options={'ordering': ('device_type__id', 'parent__id', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='modulebay',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='modulebaytemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='poweroutlet',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='poweroutlettemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='powerport',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='powerporttemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='rack',
|
||||
options={'ordering': ('site', 'location', 'name', 'pk')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='rearport',
|
||||
options={'ordering': ('device', 'name')},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='rearporttemplate',
|
||||
options={'ordering': ('device_type', 'module_type', 'name')},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='consoleport',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='consoleporttemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='consoleserverport',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='consoleserverporttemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='device',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='devicebay',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='devicebaytemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='frontport',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='frontporttemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inventoryitem',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='inventoryitemtemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='modulebay',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='modulebaytemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='poweroutlet',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='poweroutlettemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='powerport',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='powerporttemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='rack',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='rearport',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='rearporttemplate',
|
||||
name='_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='site',
|
||||
name='_name',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='consoleport',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='consoleporttemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='consoleserverport',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='consoleserverporttemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='device',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, db_collation='natural_sort', max_length=64, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='devicebay',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='devicebaytemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='frontport',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='frontporttemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='interface',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='interfacetemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventoryitem',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='inventoryitemtemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='modulebay',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='modulebaytemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='poweroutlet',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='poweroutlettemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='powerport',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='powerporttemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rack',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=100),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rearport',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='rearporttemplate',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
]
|
@ -1,22 +0,0 @@
|
||||
# Generated by Django 5.0.9 on 2024-11-12 22:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0197_auto_20241112_2221'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='site',
|
||||
options={'ordering': ('name',)},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='site',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=100, unique=True),
|
||||
),
|
||||
]
|
@ -44,12 +44,8 @@ class ComponentTemplateModel(ChangeLoggedModel, TrackingModelMixin):
|
||||
max_length=64,
|
||||
help_text=_(
|
||||
"{module} is accepted as a substitution for the module bay position when attached to a module type."
|
||||
)
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
),
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
label = models.CharField(
|
||||
verbose_name=_('label'),
|
||||
@ -65,7 +61,7 @@ class ComponentTemplateModel(ChangeLoggedModel, TrackingModelMixin):
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
ordering = ('device_type', '_name')
|
||||
ordering = ('device_type', 'name')
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=('device_type', 'name'),
|
||||
@ -125,7 +121,7 @@ class ModularComponentTemplateModel(ComponentTemplateModel):
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
ordering = ('device_type', 'module_type', '_name')
|
||||
ordering = ('device_type', 'module_type', 'name')
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=('device_type', 'name'),
|
||||
@ -782,7 +778,7 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel):
|
||||
component_model = InventoryItem
|
||||
|
||||
class Meta:
|
||||
ordering = ('device_type__id', 'parent__id', '_name')
|
||||
ordering = ('device_type__id', 'parent__id', 'name')
|
||||
indexes = (
|
||||
models.Index(fields=('component_type', 'component_id')),
|
||||
)
|
||||
|
@ -50,12 +50,8 @@ class ComponentModel(NetBoxModel):
|
||||
)
|
||||
name = models.CharField(
|
||||
verbose_name=_('name'),
|
||||
max_length=64
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
max_length=64,
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
label = models.CharField(
|
||||
verbose_name=_('label'),
|
||||
@ -71,7 +67,7 @@ class ComponentModel(NetBoxModel):
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
ordering = ('device', '_name')
|
||||
ordering = ('device', 'name')
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
fields=('device', 'name'),
|
||||
@ -1301,7 +1297,7 @@ class InventoryItem(MPTTModel, ComponentModel, TrackingModelMixin):
|
||||
clone_fields = ('device', 'parent', 'role', 'manufacturer', 'status', 'part_id')
|
||||
|
||||
class Meta:
|
||||
ordering = ('device__id', 'parent__id', '_name')
|
||||
ordering = ('device__id', 'parent__id', 'name')
|
||||
indexes = (
|
||||
models.Index(fields=('component_type', 'component_id')),
|
||||
)
|
||||
|
@ -23,7 +23,7 @@ from netbox.config import ConfigItem
|
||||
from netbox.models import OrganizationalModel, PrimaryModel
|
||||
from netbox.models.mixins import WeightMixin
|
||||
from netbox.models.features import ContactsMixin, ImageAttachmentsMixin
|
||||
from utilities.fields import ColorField, CounterCacheField, NaturalOrderingField
|
||||
from utilities.fields import ColorField, CounterCacheField
|
||||
from utilities.tracking import TrackingModelMixin
|
||||
from .device_components import *
|
||||
from .mixins import RenderConfigMixin
|
||||
@ -582,13 +582,8 @@ class Device(
|
||||
verbose_name=_('name'),
|
||||
max_length=64,
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True,
|
||||
null=True
|
||||
null=True,
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
serial = models.CharField(
|
||||
max_length=50,
|
||||
@ -775,7 +770,7 @@ class Device(
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ('_name', 'pk') # Name may be null
|
||||
ordering = ('name', 'pk') # Name may be null
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
Lower('name'), 'site', 'tenant',
|
||||
|
@ -19,7 +19,7 @@ from netbox.models.mixins import WeightMixin
|
||||
from netbox.models.features import ContactsMixin, ImageAttachmentsMixin
|
||||
from utilities.conversion import to_grams
|
||||
from utilities.data import array_to_string, drange
|
||||
from utilities.fields import ColorField, NaturalOrderingField
|
||||
from utilities.fields import ColorField
|
||||
from .device_components import PowerPort
|
||||
from .devices import Device, Module
|
||||
from .power import PowerFeed
|
||||
@ -255,12 +255,8 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
||||
)
|
||||
name = models.CharField(
|
||||
verbose_name=_('name'),
|
||||
max_length=100
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
facility_id = models.CharField(
|
||||
max_length=50,
|
||||
@ -340,7 +336,7 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ('site', 'location', '_name', 'pk') # (site, location, name) may be non-unique
|
||||
ordering = ('site', 'location', 'name', 'pk') # (site, location, name) may be non-unique
|
||||
constraints = (
|
||||
# Name and facility_id must be unique *only* within a Location
|
||||
models.UniqueConstraint(
|
||||
|
@ -8,7 +8,6 @@ from dcim.choices import *
|
||||
from dcim.constants import *
|
||||
from netbox.models import NestedGroupModel, PrimaryModel
|
||||
from netbox.models.features import ContactsMixin, ImageAttachmentsMixin
|
||||
from utilities.fields import NaturalOrderingField
|
||||
|
||||
__all__ = (
|
||||
'Location',
|
||||
@ -146,11 +145,6 @@ class Site(ContactsMixin, ImageAttachmentsMixin, PrimaryModel):
|
||||
help_text=_("Full name of the site"),
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
)
|
||||
slug = models.SlugField(
|
||||
verbose_name=_('slug'),
|
||||
max_length=100,
|
||||
|
@ -5,7 +5,7 @@ from django.db import models
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from utilities.ordering import naturalize
|
||||
from utilities.ordering import naturalize_interface
|
||||
from .forms.widgets import ColorSelect
|
||||
from .validators import ColorValidator
|
||||
|
||||
@ -40,7 +40,7 @@ class NaturalOrderingField(models.CharField):
|
||||
"""
|
||||
description = "Stores a representation of its target field suitable for natural ordering"
|
||||
|
||||
def __init__(self, target_field, naturalize_function=naturalize, *args, **kwargs):
|
||||
def __init__(self, target_field, naturalize_function=naturalize_interface, *args, **kwargs):
|
||||
self.target_field = target_field
|
||||
self.naturalize_function = naturalize_function
|
||||
super().__init__(*args, **kwargs)
|
||||
|
@ -0,0 +1,37 @@
|
||||
# Generated by Django 5.0.9 on 2024-11-13 16:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('virtualization', '0045_clusters_cached_relations'),
|
||||
('dcim', '0197_natural_sort'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='virtualmachine',
|
||||
options={'ordering': ('name', 'pk')},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='virtualmachine',
|
||||
name='_name',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='virtualdisk',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='virtualmachine',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='vminterface',
|
||||
name='name',
|
||||
field=models.CharField(db_collation='natural_sort', max_length=64),
|
||||
),
|
||||
]
|
@ -69,12 +69,8 @@ class VirtualMachine(ContactsMixin, ImageAttachmentsMixin, RenderConfigMixin, Co
|
||||
)
|
||||
name = models.CharField(
|
||||
verbose_name=_('name'),
|
||||
max_length=64
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
max_length=64,
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=50,
|
||||
@ -152,7 +148,7 @@ class VirtualMachine(ContactsMixin, ImageAttachmentsMixin, RenderConfigMixin, Co
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ('_name', 'pk') # Name may be non-unique
|
||||
ordering = ('name', 'pk') # Name may be non-unique
|
||||
constraints = (
|
||||
models.UniqueConstraint(
|
||||
Lower('name'), 'cluster', 'tenant',
|
||||
@ -273,7 +269,8 @@ class ComponentModel(NetBoxModel):
|
||||
)
|
||||
name = models.CharField(
|
||||
verbose_name=_('name'),
|
||||
max_length=64
|
||||
max_length=64,
|
||||
db_collation="natural_sort"
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
|
Loading…
Reference in New Issue
Block a user