diff --git a/netbox/dcim/migrations/0089_deterministic_ordering.py b/netbox/dcim/migrations/0089_deterministic_ordering.py new file mode 100644 index 000000000..6944cff00 --- /dev/null +++ b/netbox/dcim/migrations/0089_deterministic_ordering.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.8 on 2020-01-15 18:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0088_powerfeed_available_power'), + ] + + 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')}, + ), + ] diff --git a/netbox/dcim/models/__init__.py b/netbox/dcim/models/__init__.py index c51f83c35..737c5ab1f 100644 --- a/netbox/dcim/models/__init__.py +++ b/netbox/dcim/models/__init__.py @@ -594,8 +594,9 @@ class Rack(ChangeLoggedModel, CustomFieldModel, RackElevationHelperMixin): } class Meta: - ordering = ['site', 'group', 'name'] + 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'], ] @@ -1392,7 +1393,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel): } class Meta: - ordering = ['name'] + ordering = ('name', 'pk') # Name may be NULL unique_together = [ ['site', 'tenant', 'name'], # See validate_unique below ['rack', 'position', 'face'], diff --git a/netbox/extras/migrations/0035_deterministic_ordering.py b/netbox/extras/migrations/0035_deterministic_ordering.py new file mode 100644 index 000000000..d1904c75d --- /dev/null +++ b/netbox/extras/migrations/0035_deterministic_ordering.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.8 on 2020-01-15 18:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0034_configcontext_tags'), + ] + + operations = [ + migrations.AlterModelOptions( + name='customfieldvalue', + options={'ordering': ('obj_type', 'obj_id', 'pk')}, + ), + migrations.AlterModelOptions( + name='graph', + options={'ordering': ('type', 'weight', 'name', 'pk')}, + ), + migrations.AlterModelOptions( + name='imageattachment', + options={'ordering': ('name', 'pk')}, + ), + migrations.AlterModelOptions( + name='webhook', + options={'ordering': ('name',)}, + ), + ] diff --git a/netbox/extras/models.py b/netbox/extras/models.py index c4db020e9..147963589 100644 --- a/netbox/extras/models.py +++ b/netbox/extras/models.py @@ -120,6 +120,7 @@ class Webhook(models.Model): ) class Meta: + ordering = ('name',) unique_together = ('payload_url', 'type_create', 'type_update', 'type_delete',) def __str__(self): @@ -308,8 +309,8 @@ class CustomFieldValue(models.Model): ) class Meta: - ordering = ['obj_type', 'obj_id'] - unique_together = ['field', 'obj_type', 'obj_id'] + ordering = ('obj_type', 'obj_id', 'pk') # (obj_type, obj_id) may be non-unique + unique_together = ('field', 'obj_type', 'obj_id') def __str__(self): return '{} {}'.format(self.obj, self.field) @@ -454,7 +455,7 @@ class Graph(models.Model): ) class Meta: - ordering = ['type', 'weight', 'name'] + ordering = ('type', 'weight', 'name', 'pk') # (type, weight, name) may be non-unique def __str__(self): return self.name @@ -623,7 +624,7 @@ class ImageAttachment(models.Model): ) class Meta: - ordering = ['name'] + ordering = ('name', 'pk') # name may be non-unique def __str__(self): if self.name: diff --git a/netbox/ipam/migrations/0033_deterministic_ordering.py b/netbox/ipam/migrations/0033_deterministic_ordering.py new file mode 100644 index 000000000..4fa5d890c --- /dev/null +++ b/netbox/ipam/migrations/0033_deterministic_ordering.py @@ -0,0 +1,42 @@ +# Generated by Django 2.2.8 on 2020-01-15 18:10 + +from django.db import migrations +import django.db.models.expressions + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0032_role_description'), + ] + + operations = [ + migrations.AlterModelOptions( + name='aggregate', + options={'ordering': ('family', 'prefix', 'pk')}, + ), + migrations.AlterModelOptions( + name='ipaddress', + options={'ordering': ('family', 'address', 'pk'), 'verbose_name': 'IP address', 'verbose_name_plural': 'IP addresses'}, + ), + migrations.AlterModelOptions( + name='prefix', + options={'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'family', 'prefix', 'pk'), 'verbose_name_plural': 'prefixes'}, + ), + migrations.AlterModelOptions( + name='service', + options={'ordering': ('protocol', 'port', 'pk')}, + ), + migrations.AlterModelOptions( + name='vlan', + options={'ordering': ('site', 'group', 'vid', 'pk'), 'verbose_name': 'VLAN', 'verbose_name_plural': 'VLANs'}, + ), + migrations.AlterModelOptions( + name='vlangroup', + options={'ordering': ('site', 'name', 'pk'), 'verbose_name': 'VLAN group', 'verbose_name_plural': 'VLAN groups'}, + ), + migrations.AlterModelOptions( + name='vrf', + options={'ordering': ('name', 'rd', 'pk'), 'verbose_name': 'VRF', 'verbose_name_plural': 'VRFs'}, + ), + ] diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 5c2a75482..ed0b8f4a7 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -87,7 +87,7 @@ class VRF(ChangeLoggedModel, CustomFieldModel): ] class Meta: - ordering = ['name', 'rd'] + ordering = ('name', 'rd', 'pk') # (name, rd) may be non-unique verbose_name = 'VRF' verbose_name_plural = 'VRFs' @@ -189,7 +189,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel): ] class Meta: - ordering = ['family', 'prefix'] + ordering = ('family', 'prefix', 'pk') # (family, prefix) may be non-unique def __str__(self): return str(self.prefix) @@ -383,7 +383,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): } class Meta: - ordering = [F('vrf').asc(nulls_first=True), 'family', 'prefix'] + ordering = (F('vrf').asc(nulls_first=True), 'family', 'prefix', 'pk') # (vrf, family, prefix) may be non-unique verbose_name_plural = 'prefixes' def __str__(self): @@ -666,7 +666,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): } class Meta: - ordering = ['family', 'address'] + ordering = ('family', 'address', 'pk') # (family, address) may be non-unique verbose_name = 'IP address' verbose_name_plural = 'IP addresses' @@ -829,7 +829,7 @@ class VLANGroup(ChangeLoggedModel): csv_headers = ['name', 'slug', 'site'] class Meta: - ordering = ['site', 'name'] + ordering = ('site', 'name', 'pk') # (site, name) may be non-unique unique_together = [ ['site', 'name'], ['site', 'slug'], @@ -934,7 +934,7 @@ class VLAN(ChangeLoggedModel, CustomFieldModel): } class Meta: - ordering = ['site', 'group', 'vid'] + ordering = ('site', 'group', 'vid', 'pk') # (site, group, vid) may be non-unique unique_together = [ ['group', 'vid'], ['group', 'name'], @@ -1037,7 +1037,7 @@ class Service(ChangeLoggedModel, CustomFieldModel): csv_headers = ['device', 'virtual_machine', 'name', 'protocol', 'description'] class Meta: - ordering = ['protocol', 'port'] + ordering = ('protocol', 'port', 'pk') # (protocol, port) may be non-unique def __str__(self): return '{} ({}/{})'.format(self.name, self.port, self.get_protocol_display()) diff --git a/netbox/virtualization/migrations/0013_deterministic_ordering.py b/netbox/virtualization/migrations/0013_deterministic_ordering.py new file mode 100644 index 000000000..b5b0451a1 --- /dev/null +++ b/netbox/virtualization/migrations/0013_deterministic_ordering.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.8 on 2020-01-15 18:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('virtualization', '0012_vm_name_nonunique'), + ] + + operations = [ + migrations.AlterModelOptions( + name='virtualmachine', + options={'ordering': ('name', 'pk')}, + ), + ] diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index 54dc2d246..3ec5ccf8e 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -273,7 +273,7 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel): } class Meta: - ordering = ['name'] + ordering = ('name', 'pk') # Name may be non-unique unique_together = [ ['cluster', 'tenant', 'name'] ]