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

Closes #18022: Extend linter (ruff) to enforce line length limit (120 chars) (#18067)

* Enable E501 rule
* Configure ruff formatter
* Reformat migration files to fix line length violations
* Fix various E501 errors
* Move table template code to template_code.py & ignore E501 errors
* Reformat raw SQL
Jeremy Stretch 1 год назад
Родитель
Сommit
343a4af591
100 измененных файлов с 3730 добавлено и 917 удалено
  1. 6 5
      netbox/circuits/api/serializers_/circuits.py
  2. 5 3
      netbox/circuits/filtersets.py
  3. 4 1
      netbox/circuits/forms/filtersets.py
  4. 7 4
      netbox/circuits/migrations/0001_squashed.py
  5. 59 12
      netbox/circuits/migrations/0002_squashed_0029.py
  6. 1 2
      netbox/circuits/migrations/0003_squashed_0037.py
  7. 35 10
      netbox/circuits/migrations/0038_squashed_0042.py
  8. 0 1
      netbox/circuits/migrations/0044_circuit_groups.py
  9. 0 1
      netbox/circuits/migrations/0045_circuit_distance.py
  10. 1 5
      netbox/circuits/migrations/0046_charfield_null_choices.py
  11. 6 10
      netbox/circuits/migrations/0047_circuittermination__termination.py
  12. 1 7
      netbox/circuits/migrations/0048_circuitterminations_cached_relations.py
  13. 0 1
      netbox/circuits/migrations/0049_natural_ordering.py
  14. 58 10
      netbox/circuits/migrations/0050_virtual_circuits.py
  15. 3 1
      netbox/circuits/models/circuits.py
  16. 2 1
      netbox/circuits/tables/circuits.py
  17. 9 3
      netbox/circuits/tests/test_api.py
  18. 129 15
      netbox/circuits/tests/test_filtersets.py
  19. 9 3
      netbox/circuits/tests/test_views.py
  20. 25 5
      netbox/circuits/urls.py
  21. 4 1
      netbox/core/api/schema.py
  22. 2 2
      netbox/core/api/serializers_/jobs.py
  23. 83 13
      netbox/core/migrations/0001_squashed_0005.py
  24. 0 1
      netbox/core/migrations/0006_datasource_type_remove_choices.py
  25. 0 1
      netbox/core/migrations/0007_job_add_error_field.py
  26. 1 3
      netbox/core/migrations/0008_contenttype_proxy.py
  27. 0 1
      netbox/core/migrations/0009_configrevision.py
  28. 0 1
      netbox/core/migrations/0010_gfk_indexes.py
  29. 38 5
      netbox/core/migrations/0011_move_objectchange.py
  30. 1 2
      netbox/core/migrations/0012_job_object_type_optional.py
  31. 7 2
      netbox/core/models/files.py
  32. 11 1
      netbox/core/models/jobs.py
  33. 20 4
      netbox/core/urls.py
  34. 3 3
      netbox/dcim/api/serializers_/device_components.py
  35. 2 2
      netbox/dcim/filtersets.py
  36. 10 4
      netbox/dcim/forms/bulk_import.py
  37. 4 1
      netbox/dcim/forms/common.py
  38. 8 2
      netbox/dcim/forms/connections.py
  39. 18 8
      netbox/dcim/forms/model_forms.py
  40. 2 1
      netbox/dcim/forms/object_create.py
  41. 2 1
      netbox/dcim/forms/object_import.py
  42. 12 4
      netbox/dcim/graphql/types.py
  43. 251 40
      netbox/dcim/migrations/0001_squashed.py
  44. 227 46
      netbox/dcim/migrations/0002_squashed.py
  45. 225 40
      netbox/dcim/migrations/0003_squashed_0130.py
  46. 470 66
      netbox/dcim/migrations/0131_squashed_0159.py
  47. 185 45
      netbox/dcim/migrations/0160_squashed_0166.py
  48. 125 34
      netbox/dcim/migrations/0167_squashed_0182.py
  49. 7 2
      netbox/dcim/migrations/0184_protect_child_interfaces.py
  50. 0 1
      netbox/dcim/migrations/0185_gfk_indexes.py
  51. 0 1
      netbox/dcim/migrations/0186_location_facility.py
  52. 0 1
      netbox/dcim/migrations/0187_alter_device_vc_position.py
  53. 26 22
      netbox/dcim/migrations/0188_racktype.py
  54. 0 1
      netbox/dcim/migrations/0189_moduletype_rack_airflow.py
  55. 35 7
      netbox/dcim/migrations/0190_nested_modules.py
  56. 1 5
      netbox/dcim/migrations/0191_module_bay_rebuild.py
  57. 0 1
      netbox/dcim/migrations/0192_inventoryitem_status.py
  58. 0 1
      netbox/dcim/migrations/0193_poweroutlet_color.py
  59. 1 5
      netbox/dcim/migrations/0194_charfield_null_choices.py
  60. 3 2
      netbox/dcim/migrations/0195_interface_vlan_translation_policy.py
  61. 14 3
      netbox/dcim/migrations/0196_qinq_svlan.py
  62. 3 4
      netbox/dcim/migrations/0197_natural_sort_collation.py
  63. 0 1
      netbox/dcim/migrations/0198_natural_ordering.py
  64. 22 7
      netbox/dcim/migrations/0199_macaddress.py
  65. 3 9
      netbox/dcim/migrations/0200_populate_mac_addresses.py
  66. 18 6
      netbox/dcim/models/device_component_templates.py
  67. 16 6
      netbox/dcim/models/devices.py
  68. 3 1
      netbox/dcim/models/racks.py
  69. 4 1
      netbox/dcim/svg/racks.py
  70. 8 6
      netbox/dcim/tables/devices.py
  71. 72 15
      netbox/dcim/tests/test_api.py
  72. 214 48
      netbox/dcim/tests/test_cablepaths.py
  73. 705 103
      netbox/dcim/tests/test_filtersets.py
  74. 23 4
      netbox/dcim/tests/test_models.py
  75. 137 32
      netbox/dcim/tests/test_views.py
  76. 12 4
      netbox/dcim/views.py
  77. 2 1
      netbox/extras/management/commands/reindex.py
  78. 98 16
      netbox/extras/migrations/0001_squashed.py
  79. 0 1
      netbox/extras/migrations/0002_squashed_0059.py
  80. 109 18
      netbox/extras/migrations/0060_squashed_0086.py
  81. 36 11
      netbox/extras/migrations/0087_squashed_0098.py
  82. 0 1
      netbox/extras/migrations/0099_cachedvalue_ordering.py
  83. 1 5
      netbox/extras/migrations/0100_customfield_ui_attrs.py
  84. 5 7
      netbox/extras/migrations/0101_eventrule.py
  85. 1 5
      netbox/extras/migrations/0102_move_configrevision.py
  86. 9 4
      netbox/extras/migrations/0103_gfk_indexes.py
  87. 0 1
      netbox/extras/migrations/0105_customfield_min_max_values.py
  88. 0 1
      netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py
  89. 0 1
      netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py
  90. 1 5
      netbox/extras/migrations/0108_convert_reports_to_scripts.py
  91. 21 25
      netbox/extras/migrations/0109_script_model.py
  92. 0 1
      netbox/extras/migrations/0110_remove_eventrule_action_parameters.py
  93. 16 18
      netbox/extras/migrations/0111_rename_content_types.py
  94. 0 1
      netbox/extras/migrations/0112_tag_update_object_types.py
  95. 0 1
      netbox/extras/migrations/0113_customfield_rename_object_type.py
  96. 0 1
      netbox/extras/migrations/0114_customfield_add_comments.py
  97. 1 5
      netbox/extras/migrations/0115_convert_dashboard_widgets.py
  98. 1 5
      netbox/extras/migrations/0116_custom_link_button_color.py
  99. 31 49
      netbox/extras/migrations/0117_move_objectchange.py
  100. 0 1
      netbox/extras/migrations/0118_customfield_uniqueness.py

+ 6 - 5
netbox/circuits/api/serializers_/circuits.py

@@ -59,8 +59,8 @@ class CircuitCircuitTerminationSerializer(WritableNestedSerializer):
     class Meta:
         model = CircuitTermination
         fields = [
-            'id', 'url', 'display_url', 'display', 'termination_type', 'termination_id', 'termination', 'provider_network', 'port_speed', 'upstream_speed',
-            'xconnect_id', 'description',
+            'id', 'url', 'display_url', 'display', 'termination_type', 'termination_id', 'termination',
+            'provider_network', 'port_speed', 'upstream_speed', 'xconnect_id', 'description',
         ]
 
     @extend_schema_field(serializers.JSONField(allow_null=True))
@@ -138,9 +138,10 @@ class CircuitTerminationSerializer(NetBoxModelSerializer, CabledObjectSerializer
     class Meta:
         model = CircuitTermination
         fields = [
-            'id', 'url', 'display_url', 'display', 'circuit', 'term_side', 'termination_type', 'termination_id', 'termination', 'provider_network', 'port_speed',
-            'upstream_speed', 'xconnect_id', 'pp_info', 'description', 'mark_connected', 'cable', 'cable_end',
-            'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
+            'id', 'url', 'display_url', 'display', 'circuit', 'term_side', 'termination_type', 'termination_id',
+            'termination', 'provider_network', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description',
+            'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created',
+            'last_updated', '_occupied',
         ]
         brief_fields = ('id', 'url', 'display', 'circuit', 'term_side', 'description', 'cable', '_occupied')
 

+ 5 - 3
netbox/circuits/filtersets.py

@@ -241,7 +241,9 @@ class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilte
 
     class Meta:
         model = Circuit
-        fields = ('id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit')
+        fields = (
+            'id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit',
+        )
 
     def search(self, queryset, name, value):
         if not value.strip():
@@ -336,8 +338,8 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
     class Meta:
         model = CircuitTermination
         fields = (
-            'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 'mark_connected',
-            'pp_info', 'cable_end',
+            'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description',
+            'mark_connected', 'pp_info', 'cable_end',
         )
 
     def search(self, queryset, name, value):

+ 4 - 1
netbox/circuits/forms/filtersets.py

@@ -121,7 +121,10 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
     fieldsets = (
         FieldSet('q', 'filter_id', 'tag'),
         FieldSet('provider_id', 'provider_account_id', 'provider_network_id', name=_('Provider')),
-        FieldSet('type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit', name=_('Attributes')),
+        FieldSet(
+            'type_id', 'status', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit',
+            name=_('Attributes')
+        ),
         FieldSet('region_id', 'site_group_id', 'site_id', name=_('Location')),
         FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')),
         FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')),

+ 7 - 4
netbox/circuits/migrations/0001_squashed.py

@@ -5,11 +5,9 @@ import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
-
     initial = True
 
-    dependencies = [
-    ]
+    dependencies = []
 
     replaces = [
         ('circuits', '0001_initial'),
@@ -98,7 +96,12 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(max_length=100)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
-                ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider')),
+                (
+                    'provider',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider'
+                    ),
+                ),
             ],
             options={
                 'ordering': ('provider', 'name'),

+ 59 - 12
netbox/circuits/migrations/0002_squashed_0029.py

@@ -4,7 +4,6 @@ import taggit.managers
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0001_initial'),
         ('contenttypes', '0002_remove_content_type_name'),
@@ -58,32 +57,56 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='circuittermination',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='circuittermination',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='circuittermination',
             name='circuit',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.circuit'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.circuit'
+            ),
         ),
         migrations.AddField(
             model_name='circuittermination',
             name='provider_network',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='circuits.providernetwork'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='circuit_terminations',
+                to='circuits.providernetwork',
+            ),
         ),
         migrations.AddField(
             model_name='circuittermination',
             name='site',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='dcim.site'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='circuit_terminations',
+                to='dcim.site',
+            ),
         ),
         migrations.AddField(
             model_name='circuit',
             name='provider',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider'
+            ),
         ),
         migrations.AddField(
             model_name='circuit',
@@ -93,26 +116,50 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='circuit',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='circuits',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='circuit',
             name='termination_a',
-            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'),
+            field=models.ForeignKey(
+                blank=True,
+                editable=False,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='circuits.circuittermination',
+            ),
         ),
         migrations.AddField(
             model_name='circuit',
             name='termination_z',
-            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'),
+            field=models.ForeignKey(
+                blank=True,
+                editable=False,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='circuits.circuittermination',
+            ),
         ),
         migrations.AddField(
             model_name='circuit',
             name='type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.circuittype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.circuittype'
+            ),
         ),
         migrations.AddConstraint(
             model_name='providernetwork',
-            constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_provider_name'),
+            constraint=models.UniqueConstraint(
+                fields=('provider', 'name'), name='circuits_providernetwork_provider_name'
+            ),
         ),
         migrations.AlterUniqueTogether(
             name='providernetwork',

+ 1 - 2
netbox/circuits/migrations/0003_squashed_0037.py

@@ -5,7 +5,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('circuits', '0003_extend_tag_support'),
         ('circuits', '0004_rename_cable_peer'),
@@ -14,7 +13,7 @@ class Migration(migrations.Migration):
         ('circuits', '0034_created_datetimefield'),
         ('circuits', '0035_provider_asns'),
         ('circuits', '0036_circuit_termination_date_tags_custom_fields'),
-        ('circuits', '0037_new_cabling_models')
+        ('circuits', '0037_new_cabling_models'),
     ]
 
     dependencies = [

+ 35 - 10
netbox/circuits/migrations/0038_squashed_0042.py

@@ -6,13 +6,12 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('circuits', '0038_cabling_cleanup'),
         ('circuits', '0039_unique_constraints'),
         ('circuits', '0040_provider_remove_deprecated_fields'),
         ('circuits', '0041_standardize_description_comments'),
-        ('circuits', '0042_provideraccount')
+        ('circuits', '0042_provideraccount'),
     ]
 
     dependencies = [
@@ -51,11 +50,15 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='circuittermination',
-            constraint=models.UniqueConstraint(fields=('circuit', 'term_side'), name='circuits_circuittermination_unique_circuit_term_side'),
+            constraint=models.UniqueConstraint(
+                fields=('circuit', 'term_side'), name='circuits_circuittermination_unique_circuit_term_side'
+            ),
         ),
         migrations.AddConstraint(
             model_name='providernetwork',
-            constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_unique_provider_name'),
+            constraint=models.UniqueConstraint(
+                fields=('provider', 'name'), name='circuits_providernetwork_unique_provider_name'
+            ),
         ),
         migrations.RemoveField(
             model_name='provider',
@@ -84,12 +87,20 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('account', models.CharField(max_length=100)),
                 ('name', models.CharField(blank=True, max_length=100)),
-                ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='accounts', to='circuits.provider')),
+                (
+                    'provider',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='accounts', to='circuits.provider'
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],
             options={
@@ -98,11 +109,17 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='provideraccount',
-            constraint=models.UniqueConstraint(condition=models.Q(('name', ''), _negated=True), fields=('provider', 'name'), name='circuits_provideraccount_unique_provider_name'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('name', ''), _negated=True),
+                fields=('provider', 'name'),
+                name='circuits_provideraccount_unique_provider_name',
+            ),
         ),
         migrations.AddConstraint(
             model_name='provideraccount',
-            constraint=models.UniqueConstraint(fields=('provider', 'account'), name='circuits_provideraccount_unique_provider_account'),
+            constraint=models.UniqueConstraint(
+                fields=('provider', 'account'), name='circuits_provideraccount_unique_provider_account'
+            ),
         ),
         migrations.RemoveField(
             model_name='provider',
@@ -111,7 +128,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='circuit',
             name='provider_account',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provideraccount'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='circuits',
+                to='circuits.provideraccount',
+            ),
             preserve_default=False,
         ),
         migrations.AlterModelOptions(
@@ -120,6 +143,8 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='circuit',
-            constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'),
+            constraint=models.UniqueConstraint(
+                fields=('provider_account', 'cid'), name='circuits_circuit_unique_provideraccount_cid'
+            ),
         ),
     ]

+ 0 - 1
netbox/circuits/migrations/0044_circuit_groups.py

@@ -5,7 +5,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0043_circuittype_color'),
         ('extras', '0119_notifications'),

+ 0 - 1
netbox/circuits/migrations/0045_circuit_distance.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0044_circuit_groups'),
     ]

+ 1 - 5
netbox/circuits/migrations/0046_charfield_null_choices.py

@@ -15,7 +15,6 @@ def set_null_values(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0045_circuit_distance'),
     ]
@@ -36,8 +35,5 @@ class Migration(migrations.Migration):
             name='cable_end',
             field=models.CharField(blank=True, max_length=1, null=True),
         ),
-        migrations.RunPython(
-            code=set_null_values,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop),
     ]

+ 6 - 10
netbox/circuits/migrations/0047_circuittermination__termination.py

@@ -11,19 +11,17 @@ def copy_site_assignments(apps, schema_editor):
     Site = apps.get_model('dcim', 'Site')
 
     CircuitTermination.objects.filter(site__isnull=False).update(
-        termination_type=ContentType.objects.get_for_model(Site),
-        termination_id=models.F('site_id')
+        termination_type=ContentType.objects.get_for_model(Site), termination_id=models.F('site_id')
     )
 
     ProviderNetwork = apps.get_model('circuits', 'ProviderNetwork')
     CircuitTermination.objects.filter(provider_network__isnull=False).update(
         termination_type=ContentType.objects.get_for_model(ProviderNetwork),
-        termination_id=models.F('provider_network_id')
+        termination_id=models.F('provider_network_id'),
     )
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0046_charfield_null_choices'),
         ('contenttypes', '0002_remove_content_type_name'),
@@ -41,17 +39,15 @@ class Migration(migrations.Migration):
             name='termination_type',
             field=models.ForeignKey(
                 blank=True,
-                limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'providernetwork'))),
+                limit_choices_to=models.Q(
+                    ('model__in', ('region', 'sitegroup', 'site', 'location', 'providernetwork'))
+                ),
                 null=True,
                 on_delete=django.db.models.deletion.PROTECT,
                 related_name='+',
                 to='contenttypes.contenttype',
             ),
         ),
-
         # Copy over existing site assignments
-        migrations.RunPython(
-            code=copy_site_assignments,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=copy_site_assignments, reverse_code=migrations.RunPython.noop),
     ]

+ 1 - 7
netbox/circuits/migrations/0048_circuitterminations_cached_relations.py

@@ -20,7 +20,6 @@ def populate_denormalized_fields(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0047_circuittermination__termination'),
     ]
@@ -70,13 +69,8 @@ class Migration(migrations.Migration):
                 to='dcim.sitegroup',
             ),
         ),
-
         # Populate denormalized FK values
-        migrations.RunPython(
-            code=populate_denormalized_fields,
-            reverse_code=migrations.RunPython.noop
-        ),
-
+        migrations.RunPython(code=populate_denormalized_fields, reverse_code=migrations.RunPython.noop),
         # Delete the site ForeignKey
         migrations.RemoveField(
             model_name='circuittermination',

+ 0 - 1
netbox/circuits/migrations/0049_natural_ordering.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0048_circuitterminations_cached_relations'),
         ('dcim', '0197_natural_sort_collation'),

+ 58 - 10
netbox/circuits/migrations/0050_virtual_circuits.py

@@ -6,7 +6,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('circuits', '0049_natural_ordering'),
         ('dcim', '0196_qinq_svlan'),
@@ -21,15 +20,43 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('cid', models.CharField(max_length=100)),
                 ('status', models.CharField(default='active', max_length=50)),
-                ('provider_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_circuits', to='circuits.provideraccount')),
-                ('provider_network', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_circuits', to='circuits.providernetwork')),
+                (
+                    'provider_account',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='virtual_circuits',
+                        to='circuits.provideraccount',
+                    ),
+                ),
+                (
+                    'provider_network',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='virtual_circuits',
+                        to='circuits.providernetwork',
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
-                ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_circuits', to='tenancy.tenant')),
+                (
+                    'tenant',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='virtual_circuits',
+                        to='tenancy.tenant',
+                    ),
+                ),
             ],
             options={
                 'verbose_name': 'circuit',
@@ -43,12 +70,29 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('role', models.CharField(default='peer', max_length=50)),
                 ('description', models.CharField(blank=True, max_length=200)),
-                ('interface', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='virtual_circuit_termination', to='dcim.interface')),
+                (
+                    'interface',
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='virtual_circuit_termination',
+                        to='dcim.interface',
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
-                ('virtual_circuit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.virtualcircuit')),
+                (
+                    'virtual_circuit',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='terminations',
+                        to='circuits.virtualcircuit',
+                    ),
+                ),
             ],
             options={
                 'verbose_name': 'virtual circuit termination',
@@ -58,10 +102,14 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='virtualcircuit',
-            constraint=models.UniqueConstraint(fields=('provider_network', 'cid'), name='circuits_virtualcircuit_unique_provider_network_cid'),
+            constraint=models.UniqueConstraint(
+                fields=('provider_network', 'cid'), name='circuits_virtualcircuit_unique_provider_network_cid'
+            ),
         ),
         migrations.AddConstraint(
             model_name='virtualcircuit',
-            constraint=models.UniqueConstraint(fields=('provider_account', 'cid'), name='circuits_virtualcircuit_unique_provideraccount_cid'),
+            constraint=models.UniqueConstraint(
+                fields=('provider_account', 'cid'), name='circuits_virtualcircuit_unique_provideraccount_cid'
+            ),
         ),
     ]

+ 3 - 1
netbox/circuits/models/circuits.py

@@ -11,7 +11,9 @@ from circuits.constants import *
 from dcim.models import CabledObjectModel
 from netbox.models import ChangeLoggedModel, OrganizationalModel, PrimaryModel
 from netbox.models.mixins import DistanceMixin
-from netbox.models.features import ContactsMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, ImageAttachmentsMixin, TagsMixin
+from netbox.models.features import (
+    ContactsMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, ImageAttachmentsMixin, TagsMixin,
+)
 from utilities.fields import ColorField
 
 __all__ = (

+ 2 - 1
netbox/circuits/tables/circuits.py

@@ -42,7 +42,8 @@ class CircuitTypeTable(NetBoxTable):
     class Meta(NetBoxTable.Meta):
         model = CircuitType
         fields = (
-            'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'tags', 'created', 'last_updated', 'actions',
+            'pk', 'id', 'name', 'circuit_count', 'color', 'description', 'slug', 'tags', 'created', 'last_updated',
+            'actions',
         )
         default_columns = ('pk', 'name', 'circuit_count', 'description', 'slug')
 

+ 9 - 3
netbox/circuits/tests/test_api.py

@@ -121,9 +121,15 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
         CircuitType.objects.bulk_create(circuit_types)
 
         circuits = (
-            Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]),
-            Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]),
-            Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]),
+            Circuit(
+                cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]
+            ),
+            Circuit(
+                cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]
+            ),
+            Circuit(
+                cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuit_types[0]
+            ),
         )
         Circuit.objects.bulk_create(circuits)
 

+ 129 - 15
netbox/circuits/tests/test_filtersets.py

@@ -226,12 +226,80 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
         ProviderNetwork.objects.bulk_create(provider_networks)
 
         circuits = (
-            Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 1', install_date='2020-01-01', termination_date='2021-01-01', commit_rate=1000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar1', distance=10, distance_unit=DistanceUnitChoices.UNIT_FOOT),
-            Circuit(provider=providers[0], provider_account=provider_accounts[0], tenant=tenants[0], type=circuit_types[0], cid='Test Circuit 2', install_date='2020-01-02', termination_date='2021-01-02', commit_rate=2000, status=CircuitStatusChoices.STATUS_ACTIVE, description='foobar2', distance=20, distance_unit=DistanceUnitChoices.UNIT_METER),
-            Circuit(provider=providers[0], provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[0], cid='Test Circuit 3', install_date='2020-01-03', termination_date='2021-01-03', commit_rate=3000, status=CircuitStatusChoices.STATUS_PLANNED, distance=30, distance_unit=DistanceUnitChoices.UNIT_METER),
-            Circuit(provider=providers[1], provider_account=provider_accounts[1], tenant=tenants[1], type=circuit_types[1], cid='Test Circuit 4', install_date='2020-01-04', termination_date='2021-01-04', commit_rate=4000, status=CircuitStatusChoices.STATUS_PLANNED),
-            Circuit(provider=providers[1], provider_account=provider_accounts[2], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 5', install_date='2020-01-05', termination_date='2021-01-05', commit_rate=5000, status=CircuitStatusChoices.STATUS_OFFLINE),
-            Circuit(provider=providers[1], provider_account=provider_accounts[2], tenant=tenants[2], type=circuit_types[1], cid='Test Circuit 6', install_date='2020-01-06', termination_date='2021-01-06', commit_rate=6000, status=CircuitStatusChoices.STATUS_OFFLINE),
+            Circuit(
+                provider=providers[0],
+                provider_account=provider_accounts[0],
+                tenant=tenants[0],
+                type=circuit_types[0],
+                cid='Test Circuit 1',
+                install_date='2020-01-01',
+                termination_date='2021-01-01',
+                commit_rate=1000,
+                status=CircuitStatusChoices.STATUS_ACTIVE,
+                description='foobar1',
+                distance=10,
+                distance_unit=DistanceUnitChoices.UNIT_FOOT,
+            ),
+            Circuit(
+                provider=providers[0],
+                provider_account=provider_accounts[0],
+                tenant=tenants[0],
+                type=circuit_types[0],
+                cid='Test Circuit 2',
+                install_date='2020-01-02',
+                termination_date='2021-01-02',
+                commit_rate=2000,
+                status=CircuitStatusChoices.STATUS_ACTIVE,
+                description='foobar2',
+                distance=20,
+                distance_unit=DistanceUnitChoices.UNIT_METER,
+            ),
+            Circuit(
+                provider=providers[0],
+                provider_account=provider_accounts[1],
+                tenant=tenants[1],
+                type=circuit_types[0],
+                cid='Test Circuit 3',
+                install_date='2020-01-03',
+                termination_date='2021-01-03',
+                commit_rate=3000,
+                status=CircuitStatusChoices.STATUS_PLANNED,
+                distance=30,
+                distance_unit=DistanceUnitChoices.UNIT_METER,
+            ),
+            Circuit(
+                provider=providers[1],
+                provider_account=provider_accounts[1],
+                tenant=tenants[1],
+                type=circuit_types[1],
+                cid='Test Circuit 4',
+                install_date='2020-01-04',
+                termination_date='2021-01-04',
+                commit_rate=4000,
+                status=CircuitStatusChoices.STATUS_PLANNED,
+            ),
+            Circuit(
+                provider=providers[1],
+                provider_account=provider_accounts[2],
+                tenant=tenants[2],
+                type=circuit_types[1],
+                cid='Test Circuit 5',
+                install_date='2020-01-05',
+                termination_date='2021-01-05',
+                commit_rate=5000,
+                status=CircuitStatusChoices.STATUS_OFFLINE,
+            ),
+            Circuit(
+                provider=providers[1],
+                provider_account=provider_accounts[2],
+                tenant=tenants[2],
+                type=circuit_types[1],
+                cid='Test Circuit 6',
+                install_date='2020-01-06',
+                termination_date='2021-01-06',
+                commit_rate=6000,
+                status=CircuitStatusChoices.STATUS_OFFLINE,
+            ),
         )
         Circuit.objects.bulk_create(circuits)
 
@@ -387,18 +455,64 @@ class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
         Circuit.objects.bulk_create(circuits)
 
-        circuit_terminations = ((
-            CircuitTermination(circuit=circuits[0], termination=sites[0], term_side='A', port_speed=1000, upstream_speed=1000, xconnect_id='ABC', description='foobar1'),
-            CircuitTermination(circuit=circuits[0], termination=sites[1], term_side='Z', port_speed=1000, upstream_speed=1000, xconnect_id='DEF', description='foobar2'),
-            CircuitTermination(circuit=circuits[1], termination=sites[1], term_side='A', port_speed=2000, upstream_speed=2000, xconnect_id='GHI'),
-            CircuitTermination(circuit=circuits[1], termination=sites[2], term_side='Z', port_speed=2000, upstream_speed=2000, xconnect_id='JKL'),
-            CircuitTermination(circuit=circuits[2], termination=sites[2], term_side='A', port_speed=3000, upstream_speed=3000, xconnect_id='MNO'),
-            CircuitTermination(circuit=circuits[2], termination=sites[0], term_side='Z', port_speed=3000, upstream_speed=3000, xconnect_id='PQR'),
+        circuit_terminations = (
+            CircuitTermination(
+                circuit=circuits[0],
+                termination=sites[0],
+                term_side='A',
+                port_speed=1000,
+                upstream_speed=1000,
+                xconnect_id='ABC',
+                description='foobar1',
+            ),
+            CircuitTermination(
+                circuit=circuits[0],
+                termination=sites[1],
+                term_side='Z',
+                port_speed=1000,
+                upstream_speed=1000,
+                xconnect_id='DEF',
+                description='foobar2',
+            ),
+            CircuitTermination(
+                circuit=circuits[1],
+                termination=sites[1],
+                term_side='A',
+                port_speed=2000,
+                upstream_speed=2000,
+                xconnect_id='GHI',
+            ),
+            CircuitTermination(
+                circuit=circuits[1],
+                termination=sites[2],
+                term_side='Z',
+                port_speed=2000,
+                upstream_speed=2000,
+                xconnect_id='JKL',
+            ),
+            CircuitTermination(
+                circuit=circuits[2],
+                termination=sites[2],
+                term_side='A',
+                port_speed=3000,
+                upstream_speed=3000,
+                xconnect_id='MNO',
+            ),
+            CircuitTermination(
+                circuit=circuits[2],
+                termination=sites[0],
+                term_side='Z',
+                port_speed=3000,
+                upstream_speed=3000,
+                xconnect_id='PQR',
+            ),
             CircuitTermination(circuit=circuits[3], termination=provider_networks[0], term_side='A'),
             CircuitTermination(circuit=circuits[4], termination=provider_networks[1], term_side='A'),
             CircuitTermination(circuit=circuits[5], termination=provider_networks[2], term_side='A'),
-            CircuitTermination(circuit=circuits[6], termination=provider_networks[0], term_side='A', mark_connected=True),
-        ))
+            CircuitTermination(
+                circuit=circuits[6], termination=provider_networks[0], term_side='A', mark_connected=True
+            ),
+        )
         for ct in circuit_terminations:
             ct.save()
 

+ 9 - 3
netbox/circuits/tests/test_views.py

@@ -141,9 +141,15 @@ class CircuitTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         CircuitType.objects.bulk_create(circuittypes)
 
         circuits = (
-            Circuit(cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]),
-            Circuit(cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]),
-            Circuit(cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]),
+            Circuit(
+                cid='Circuit 1', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]
+            ),
+            Circuit(
+                cid='Circuit 2', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]
+            ),
+            Circuit(
+                cid='Circuit 3', provider=providers[0], provider_account=provider_accounts[0], type=circuittypes[0]
+            ),
         )
 
         Circuit.objects.bulk_create(circuits)

+ 25 - 5
netbox/circuits/urls.py

@@ -43,10 +43,30 @@ urlpatterns = [
     path('virtual-circuits/<int:pk>/', include(get_model_urls('circuits', 'virtualcircuit'))),
 
     # Virtual circuit terminations
-    path('virtual-circuit-terminations/', views.VirtualCircuitTerminationListView.as_view(), name='virtualcircuittermination_list'),
-    path('virtual-circuit-terminations/add/', views.VirtualCircuitTerminationEditView.as_view(), name='virtualcircuittermination_add'),
-    path('virtual-circuit-terminations/import/', views.VirtualCircuitTerminationBulkImportView.as_view(), name='virtualcircuittermination_import'),
-    path('virtual-circuit-terminations/edit/', views.VirtualCircuitTerminationBulkEditView.as_view(), name='virtualcircuittermination_bulk_edit'),
-    path('virtual-circuit-terminations/delete/', views.VirtualCircuitTerminationBulkDeleteView.as_view(), name='virtualcircuittermination_bulk_delete'),
+    path(
+        'virtual-circuit-terminations/',
+        views.VirtualCircuitTerminationListView.as_view(),
+        name='virtualcircuittermination_list',
+    ),
+    path(
+        'virtual-circuit-terminations/add/',
+        views.VirtualCircuitTerminationEditView.as_view(),
+        name='virtualcircuittermination_add',
+    ),
+    path(
+        'virtual-circuit-terminations/import/',
+        views.VirtualCircuitTerminationBulkImportView.as_view(),
+        name='virtualcircuittermination_import',
+    ),
+    path(
+        'virtual-circuit-terminations/edit/',
+        views.VirtualCircuitTerminationBulkEditView.as_view(),
+        name='virtualcircuittermination_bulk_edit',
+    ),
+    path(
+        'virtual-circuit-terminations/delete/',
+        views.VirtualCircuitTerminationBulkDeleteView.as_view(),
+        name='virtualcircuittermination_bulk_delete',
+    ),
     path('virtual-circuit-terminations/<int:pk>/', include(get_model_urls('circuits', 'virtualcircuittermination'))),
 ]

+ 4 - 1
netbox/core/api/schema.py

@@ -35,7 +35,10 @@ class ChoiceFieldFix(OpenApiSerializerFieldExtension):
 
         elif direction == "response":
             value = build_cf
-            label = {**build_basic_type(OpenApiTypes.STR), "enum": list(OrderedDict.fromkeys(self.target.choices.values()))}
+            label = {
+                **build_basic_type(OpenApiTypes.STR),
+                "enum": list(OrderedDict.fromkeys(self.target.choices.values()))
+            }
 
             return build_object_type(
                 properties={

+ 2 - 2
netbox/core/api/serializers_/jobs.py

@@ -22,7 +22,7 @@ class JobSerializer(BaseModelSerializer):
     class Meta:
         model = Job
         fields = [
-            'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', 'interval',
-            'started', 'completed', 'user', 'data', 'error', 'job_id',
+            'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled',
+            'interval', 'started', 'completed', 'user', 'data', 'error', 'job_id',
         ]
         brief_fields = ('url', 'created', 'completed', 'user', 'status')

+ 83 - 13
netbox/core/migrations/0001_squashed_0005.py

@@ -8,13 +8,12 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('core', '0001_initial'),
         ('core', '0002_managedfile'),
         ('core', '0003_job'),
         ('core', '0004_replicate_jobresults'),
-        ('core', '0005_job_created_auto_now')
+        ('core', '0005_job_created_auto_now'),
     ]
 
     dependencies = [
@@ -30,7 +29,10 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('name', models.CharField(max_length=100, unique=True)),
@@ -55,9 +57,28 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(editable=False)),
                 ('path', models.CharField(editable=False, max_length=1000)),
                 ('size', models.PositiveIntegerField(editable=False)),
-                ('hash', models.CharField(editable=False, max_length=64, validators=[django.core.validators.RegexValidator(message='Length must be 64 hexadecimal characters.', regex='^[0-9a-f]{64}$')])),
+                (
+                    'hash',
+                    models.CharField(
+                        editable=False,
+                        max_length=64,
+                        validators=[
+                            django.core.validators.RegexValidator(
+                                message='Length must be 64 hexadecimal characters.', regex='^[0-9a-f]{64}$'
+                            )
+                        ],
+                    ),
+                ),
                 ('data', models.BinaryField()),
-                ('source', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='datafiles', to='core.datasource')),
+                (
+                    'source',
+                    models.ForeignKey(
+                        editable=False,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='datafiles',
+                        to='core.datasource',
+                    ),
+                ),
             ],
             options={
                 'ordering': ('source', 'path'),
@@ -76,8 +97,18 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('object_id', models.PositiveBigIntegerField()),
-                ('datafile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.datafile')),
-                ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')),
+                (
+                    'datafile',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.datafile'
+                    ),
+                ),
+                (
+                    'object_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'
+                    ),
+                ),
             ],
             options={
                 'indexes': [models.Index(fields=['object_type', 'object_id'], name='core_autosy_object__c17bac_idx')],
@@ -97,8 +128,26 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(blank=True, editable=False, null=True)),
                 ('file_root', models.CharField(max_length=1000)),
                 ('file_path', models.FilePathField(editable=False)),
-                ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')),
-                ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')),
+                (
+                    'data_file',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to='core.datafile',
+                    ),
+                ),
+                (
+                    'data_source',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='core.datasource',
+                    ),
+                ),
                 ('auto_sync_enabled', models.BooleanField(default=False)),
             ],
             options={
@@ -108,7 +157,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='managedfile',
-            constraint=models.UniqueConstraint(fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path'),
+            constraint=models.UniqueConstraint(
+                fields=('file_root', 'file_path'), name='core_managedfile_unique_root_path'
+            ),
         ),
         migrations.CreateModel(
             name='Job',
@@ -118,14 +169,33 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(max_length=200)),
                 ('created', models.DateTimeField()),
                 ('scheduled', models.DateTimeField(blank=True, null=True)),
-                ('interval', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                (
+                    'interval',
+                    models.PositiveIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
                 ('started', models.DateTimeField(blank=True, null=True)),
                 ('completed', models.DateTimeField(blank=True, null=True)),
                 ('status', models.CharField(default='pending', max_length=30)),
                 ('data', models.JSONField(blank=True, null=True)),
                 ('job_id', models.UUIDField(unique=True)),
-                ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='contenttypes.contenttype')),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
+                (
+                    'object_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='jobs', to='contenttypes.contenttype'
+                    ),
+                ),
+                (
+                    'user',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
             ],
             options={
                 'ordering': ['-created'],

+ 0 - 1
netbox/core/migrations/0006_datasource_type_remove_choices.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0005_job_created_auto_now'),
     ]

+ 0 - 1
netbox/core/migrations/0007_job_add_error_field.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0006_datasource_type_remove_choices'),
     ]

+ 1 - 3
netbox/core/migrations/0008_contenttype_proxy.py

@@ -3,7 +3,6 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('core', '0007_job_add_error_field'),
@@ -12,8 +11,7 @@ class Migration(migrations.Migration):
     operations = [
         migrations.CreateModel(
             name='ObjectType',
-            fields=[
-            ],
+            fields=[],
             options={
                 'proxy': True,
                 'indexes': [],

+ 0 - 1
netbox/core/migrations/0009_configrevision.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0008_contenttype_proxy'),
     ]

+ 0 - 1
netbox/core/migrations/0010_gfk_indexes.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0009_configrevision'),
     ]

+ 38 - 5
netbox/core/migrations/0011_move_objectchange.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('core', '0010_gfk_indexes'),
@@ -27,15 +26,49 @@ class Migration(migrations.Migration):
                         ('object_repr', models.CharField(editable=False, max_length=200)),
                         ('prechange_data', models.JSONField(blank=True, editable=False, null=True)),
                         ('postchange_data', models.JSONField(blank=True, editable=False, null=True)),
-                        ('changed_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                        ('related_object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                        ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='changes', to=settings.AUTH_USER_MODEL)),
+                        (
+                            'changed_object_type',
+                            models.ForeignKey(
+                                on_delete=django.db.models.deletion.PROTECT,
+                                related_name='+',
+                                to='contenttypes.contenttype',
+                            ),
+                        ),
+                        (
+                            'related_object_type',
+                            models.ForeignKey(
+                                blank=True,
+                                null=True,
+                                on_delete=django.db.models.deletion.PROTECT,
+                                related_name='+',
+                                to='contenttypes.contenttype',
+                            ),
+                        ),
+                        (
+                            'user',
+                            models.ForeignKey(
+                                blank=True,
+                                null=True,
+                                on_delete=django.db.models.deletion.SET_NULL,
+                                related_name='changes',
+                                to=settings.AUTH_USER_MODEL,
+                            ),
+                        ),
                     ],
                     options={
                         'verbose_name': 'object change',
                         'verbose_name_plural': 'object changes',
                         'ordering': ['-time'],
-                        'indexes': [models.Index(fields=['changed_object_type', 'changed_object_id'], name='core_object_changed_c227ce_idx'), models.Index(fields=['related_object_type', 'related_object_id'], name='core_object_related_3375d6_idx')],
+                        'indexes': [
+                            models.Index(
+                                fields=['changed_object_type', 'changed_object_id'],
+                                name='core_object_changed_c227ce_idx',
+                            ),
+                            models.Index(
+                                fields=['related_object_type', 'related_object_id'],
+                                name='core_object_related_3375d6_idx',
+                            ),
+                        ],
                     },
                 ),
             ],

+ 1 - 2
netbox/core/migrations/0012_job_object_type_optional.py

@@ -3,7 +3,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('core', '0011_move_objectchange'),
@@ -18,7 +17,7 @@ class Migration(migrations.Migration):
                 null=True,
                 on_delete=django.db.models.deletion.CASCADE,
                 related_name='jobs',
-                to='contenttypes.contenttype'
+                to='contenttypes.contenttype',
             ),
         ),
     ]

+ 7 - 2
netbox/core/models/files.py

@@ -93,9 +93,14 @@ class ManagedFile(SyncedDataMixin, models.Model):
             self.file_path = os.path.basename(self.data_path)
 
         # Ensure that the file root and path make a unique pair
-        if self._meta.model.objects.filter(file_root=self.file_root, file_path=self.file_path).exclude(pk=self.pk).exists():
+        if self._meta.model.objects.filter(
+                file_root=self.file_root, file_path=self.file_path
+        ).exclude(pk=self.pk).exists():
             raise ValidationError(
-                f"A {self._meta.verbose_name.lower()} with this file path already exists ({self.file_root}/{self.file_path}).")
+                _("A {model} with this file path already exists ({path}).").format(
+                    model=self._meta.verbose_name.lower(),
+                    path=f"{self.file_root}/{self.file_path}"
+                ))
 
     def delete(self, *args, **kwargs):
         # Delete file from disk

+ 11 - 1
netbox/core/models/jobs.py

@@ -203,7 +203,17 @@ class Job(models.Model):
         job_end.send(self)
 
     @classmethod
-    def enqueue(cls, func, instance=None, name='', user=None, schedule_at=None, interval=None, immediate=False, **kwargs):
+    def enqueue(
+            cls,
+            func,
+            instance=None,
+            name='',
+            user=None,
+            schedule_at=None,
+            interval=None,
+            immediate=False,
+            **kwargs
+    ):
         """
         Create a Job instance and enqueue a job using the given callable
 

+ 20 - 4
netbox/core/urls.py

@@ -20,11 +20,27 @@ urlpatterns = (
 
     # Background Tasks
     path('background-queues/', views.BackgroundQueueListView.as_view(), name='background_queue_list'),
-    path('background-queues/<int:queue_index>/<str:status>/', views.BackgroundTaskListView.as_view(), name='background_task_list'),
+    path(
+        'background-queues/<int:queue_index>/<str:status>/',
+        views.BackgroundTaskListView.as_view(),
+        name='background_task_list'
+    ),
     path('background-tasks/<str:job_id>/', views.BackgroundTaskView.as_view(), name='background_task'),
-    path('background-tasks/<str:job_id>/delete/', views.BackgroundTaskDeleteView.as_view(), name='background_task_delete'),
-    path('background-tasks/<str:job_id>/requeue/', views.BackgroundTaskRequeueView.as_view(), name='background_task_requeue'),
-    path('background-tasks/<str:job_id>/enqueue/', views.BackgroundTaskEnqueueView.as_view(), name='background_task_enqueue'),
+    path(
+        'background-tasks/<str:job_id>/delete/',
+        views.BackgroundTaskDeleteView.as_view(),
+        name='background_task_delete'
+    ),
+    path(
+        'background-tasks/<str:job_id>/requeue/',
+        views.BackgroundTaskRequeueView.as_view(),
+        name='background_task_requeue'
+    ),
+    path(
+        'background-tasks/<str:job_id>/enqueue/',
+        views.BackgroundTaskEnqueueView.as_view(),
+        name='background_task_enqueue'
+    ),
     path('background-tasks/<str:job_id>/stop/', views.BackgroundTaskStopView.as_view(), name='background_task_stop'),
     path('background-workers/<int:queue_index>/', views.WorkerListView.as_view(), name='worker_list'),
     path('background-workers/<str:key>/', views.WorkerView.as_view(), name='worker'),

+ 3 - 3
netbox/dcim/api/serializers_/device_components.py

@@ -351,9 +351,9 @@ class InventoryItemSerializer(NetBoxModelSerializer):
     class Meta:
         model = InventoryItem
         fields = [
-            'id', 'url', 'display_url', 'display', 'device', 'parent', 'name', 'label', 'status', 'role', 'manufacturer',
-            'part_id', 'serial', 'asset_tag', 'discovered', 'description', 'component_type', 'component_id',
-            'component', 'tags', 'custom_fields', 'created', 'last_updated', '_depth',
+            'id', 'url', 'display_url', 'display', 'device', 'parent', 'name', 'label', 'status', 'role',
+            'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description', 'component_type',
+            'component_id', 'component', 'tags', 'custom_fields', 'created', 'last_updated', '_depth',
         ]
         brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', '_depth')
 

+ 2 - 2
netbox/dcim/filtersets.py

@@ -312,8 +312,8 @@ class RackTypeFilterSet(NetBoxModelFilterSet):
     class Meta:
         model = RackType
         fields = (
-            'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
-            'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
+            'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
+            'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
         )
 
     def search(self, queryset, name, value):

+ 10 - 4
netbox/dcim/forms/bulk_import.py

@@ -428,7 +428,10 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
 
     class Meta:
         model = ModuleType
-        fields = ['manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments', 'tags']
+        fields = [
+            'manufacturer', 'model', 'part_number', 'description', 'airflow', 'weight', 'weight_unit', 'comments',
+            'tags',
+        ]
 
 
 class DeviceRoleImportForm(NetBoxModelImportForm):
@@ -800,7 +803,10 @@ class PowerOutletImportForm(NetBoxModelImportForm):
 
     class Meta:
         model = PowerOutlet
-        fields = ('device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description', 'tags')
+        fields = (
+            'device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description',
+            'tags',
+        )
 
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -1114,8 +1120,8 @@ class InventoryItemImportForm(NetBoxModelImportForm):
     class Meta:
         model = InventoryItem
         fields = (
-            'device', 'name', 'label', 'status', 'role', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag', 'discovered',
-            'description', 'tags', 'component_type', 'component_name',
+            'device', 'name', 'label', 'status', 'role', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag',
+            'discovered', 'description', 'tags', 'component_type', 'component_name',
         )
 
     def __init__(self, *args, **kwargs):

+ 4 - 1
netbox/dcim/forms/common.py

@@ -136,7 +136,10 @@ class ModuleCommonForm(forms.Form):
 
                     if len(module_bays) != template.name.count(MODULE_TOKEN):
                         raise forms.ValidationError(
-                            _("Cannot install module with placeholder values in a module bay tree {level} in tree but {tokens} placeholders given.").format(
+                            _(
+                                "Cannot install module with placeholder values in a module bay tree {level} in tree "
+                                "but {tokens} placeholders given."
+                            ).format(
                                 level=len(module_bays), tokens=template.name.count(MODULE_TOKEN)
                             )
                         )

+ 8 - 2
netbox/dcim/forms/connections.py

@@ -111,9 +111,15 @@ def get_cable_form(a_type, b_type):
 
             if self.instance and self.instance.pk:
                 # Initialize A/B terminations when modifying an existing Cable instance
-                if a_type and self.instance.a_terminations and a_ct == ContentType.objects.get_for_model(self.instance.a_terminations[0]):
+                if (
+                        a_type and self.instance.a_terminations and
+                        a_ct == ContentType.objects.get_for_model(self.instance.a_terminations[0])
+                ):
                     self.initial['a_terminations'] = self.instance.a_terminations
-                if b_type and self.instance.b_terminations and b_ct == ContentType.objects.get_for_model(self.instance.b_terminations[0]):
+                if (
+                        b_type and self.instance.b_terminations and
+                        b_ct == ContentType.objects.get_for_model(self.instance.b_terminations[0])
+                ):
                     self.initial['b_terminations'] = self.instance.b_terminations
             else:
                 # Need to clear terminations if swapped type - but need to do it only

+ 18 - 8
netbox/dcim/forms/model_forms.py

@@ -266,7 +266,10 @@ class RackForm(TenancyForm, NetBoxModelForm):
     comments = CommentField()
 
     fieldsets = (
-        FieldSet('site', 'location', 'name', 'status', 'role', 'rack_type', 'description', 'airflow', 'tags', name=_('Rack')),
+        FieldSet(
+            'site', 'location', 'name', 'status', 'role', 'rack_type', 'description', 'airflow', 'tags',
+            name=_('Rack')
+        ),
         FieldSet('facility_id', 'serial', 'asset_tag', name=_('Inventory Control')),
         FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
     )
@@ -1007,7 +1010,8 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
     class Meta:
         model = InterfaceTemplate
         fields = [
-            'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type', 'bridge', 'rf_role',
+            'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode',
+            'poe_type', 'bridge', 'rf_role',
         ]
 
 
@@ -1189,7 +1193,10 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
                     break
         elif component_type and component_id:
             # When adding the InventoryItem from a component page
-            if content_type := ContentType.objects.filter(MODULAR_COMPONENT_TEMPLATE_MODELS).filter(pk=component_type).first():
+            content_type = ContentType.objects.filter(
+                MODULAR_COMPONENT_TEMPLATE_MODELS
+            ).filter(pk=component_type).first()
+            if content_type:
                 if component := content_type.model_class().objects.filter(pk=component_id).first():
                     initial[content_type.model] = component
 
@@ -1301,16 +1308,16 @@ class PowerOutletForm(ModularDeviceComponentForm):
 
     fieldsets = (
         FieldSet(
-            'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', 'description',
-            'tags',
+            'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected',
+            'description', 'tags',
         ),
     )
 
     class Meta:
         model = PowerOutlet
         fields = [
-            'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected', 'description',
-            'tags',
+            'device', 'module', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'mark_connected',
+            'description', 'tags',
         ]
 
 
@@ -1611,7 +1618,10 @@ class InventoryItemForm(DeviceComponentForm):
     )
 
     fieldsets = (
-        FieldSet('device', 'parent', 'name', 'label', 'status', 'role', 'description', 'tags', name=_('Inventory Item')),
+        FieldSet(
+            'device', 'parent', 'name', 'label', 'status', 'role', 'description', 'tags',
+            name=_('Inventory Item')
+        ),
         FieldSet('manufacturer', 'part_id', 'serial', 'asset_tag', name=_('Hardware')),
         FieldSet(
             TabbedGroups(

+ 2 - 1
netbox/dcim/forms/object_create.py

@@ -416,7 +416,8 @@ class VirtualChassisCreateForm(NetBoxModelForm):
     class Meta:
         model = VirtualChassis
         fields = [
-            'name', 'domain', 'description', 'region', 'site_group', 'site', 'rack', 'members', 'initial_position', 'tags',
+            'name', 'domain', 'description', 'region', 'site_group', 'site', 'rack', 'members', 'initial_position',
+            'tags',
         ]
 
     def clean(self):

+ 2 - 1
netbox/dcim/forms/object_import.py

@@ -136,7 +136,8 @@ class FrontPortTemplateImportForm(forms.ModelForm):
     class Meta:
         model = FrontPortTemplate
         fields = [
-            'device_type', 'module_type', 'name', 'type', 'color', 'rear_port', 'rear_port_position', 'label', 'description',
+            'device_type', 'module_type', 'name', 'type', 'color', 'rear_port', 'rear_port_position', 'label',
+            'description',
         ]
 
 

+ 12 - 4
netbox/dcim/graphql/types.py

@@ -482,7 +482,9 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Organi
         return self.cluster_set.all()
 
     @strawberry_django.field
-    def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]:
+    def circuit_terminations(self) -> List[
+        Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
+    ]:
         return self.circuit_terminations.all()
 
 
@@ -728,7 +730,9 @@ class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
         return self.cluster_set.all()
 
     @strawberry_django.field
-    def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]:
+    def circuit_terminations(self) -> List[
+        Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
+    ]:
         return self.circuit_terminations.all()
 
 
@@ -760,7 +764,9 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje
         return self.cluster_set.all()
 
     @strawberry_django.field
-    def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]:
+    def circuit_terminations(self) -> List[
+        Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
+    ]:
         return self.circuit_terminations.all()
 
 
@@ -784,7 +790,9 @@ class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
         return self.cluster_set.all()
 
     @strawberry_django.field
-    def circuit_terminations(self) -> List[Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]]:
+    def circuit_terminations(self) -> List[
+        Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
+    ]:
         return self.circuit_terminations.all()
 
 

+ 251 - 40
netbox/dcim/migrations/0001_squashed.py

@@ -13,11 +13,9 @@ import utilities.validators
 
 
 class Migration(migrations.Migration):
-
     initial = True
 
-    dependencies = [
-    ]
+    dependencies = []
 
     replaces = [
         ('dcim', '0001_initial'),
@@ -64,7 +62,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
@@ -83,7 +86,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(blank=True, max_length=50)),
@@ -100,7 +108,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
@@ -119,7 +132,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(blank=True, max_length=50)),
@@ -137,14 +155,34 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('local_context_data', models.JSONField(blank=True, null=True)),
                 ('name', models.CharField(blank=True, max_length=64, null=True)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize, null=True)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize, null=True
+                    ),
+                ),
                 ('serial', models.CharField(blank=True, max_length=50)),
                 ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
-                ('position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                (
+                    'position',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
                 ('face', models.CharField(blank=True, max_length=50)),
                 ('status', models.CharField(default='active', max_length=50)),
-                ('vc_position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])),
-                ('vc_priority', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])),
+                (
+                    'vc_position',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]
+                    ),
+                ),
+                (
+                    'vc_priority',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)]
+                    ),
+                ),
                 ('comments', models.TextField(blank=True)),
             ],
             options={
@@ -159,7 +197,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
             ],
@@ -174,7 +217,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
             ],
@@ -228,13 +276,27 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
                 ('mark_connected', models.BooleanField(default=False)),
                 ('type', models.CharField(max_length=50)),
-                ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+                (
+                    'rear_port_position',
+                    models.PositiveSmallIntegerField(
+                        default=1,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(1024),
+                        ],
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device', '_name'),
@@ -247,11 +309,25 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(max_length=50)),
-                ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+                (
+                    'rear_port_position',
+                    models.PositiveSmallIntegerField(
+                        default=1,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(1024),
+                        ],
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device_type', '_name'),
@@ -271,9 +347,24 @@ class Migration(migrations.Migration):
                 ('mark_connected', models.BooleanField(default=False)),
                 ('enabled', models.BooleanField(default=True)),
                 ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)),
-                ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])),
+                (
+                    'mtu',
+                    models.PositiveIntegerField(
+                        blank=True,
+                        null=True,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(65536),
+                        ],
+                    ),
+                ),
                 ('mode', models.CharField(blank=True, max_length=50)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface
+                    ),
+                ),
                 ('type', models.CharField(max_length=50)),
                 ('mgmt_only', models.BooleanField(default=False)),
             ],
@@ -290,7 +381,12 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(max_length=64)),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface
+                    ),
+                ),
                 ('type', models.CharField(max_length=50)),
                 ('mgmt_only', models.BooleanField(default=False)),
             ],
@@ -306,7 +402,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('part_id', models.CharField(blank=True, max_length=50)),
@@ -388,8 +489,19 @@ class Migration(migrations.Migration):
                 ('supply', models.CharField(default='ac', max_length=50)),
                 ('phase', models.CharField(default='single-phase', max_length=50)),
                 ('voltage', models.SmallIntegerField(validators=[utilities.validators.ExclusionValidator([0])])),
-                ('amperage', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)])),
-                ('max_utilization', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])),
+                (
+                    'amperage',
+                    models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1)]),
+                ),
+                (
+                    'max_utilization',
+                    models.PositiveSmallIntegerField(
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(100),
+                        ]
+                    ),
+                ),
                 ('available_power', models.PositiveIntegerField(default=0, editable=False)),
                 ('comments', models.TextField(blank=True)),
             ],
@@ -405,7 +517,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
@@ -424,7 +541,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(blank=True, max_length=50)),
@@ -455,14 +577,29 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
                 ('mark_connected', models.BooleanField(default=False)),
                 ('type', models.CharField(blank=True, max_length=50)),
-                ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
-                ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                (
+                    'maximum_draw',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
+                (
+                    'allocated_draw',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device', '_name'),
@@ -475,12 +612,27 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(blank=True, max_length=50)),
-                ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
-                ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                (
+                    'maximum_draw',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
+                (
+                    'allocated_draw',
+                    models.PositiveSmallIntegerField(
+                        blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device_type', '_name'),
@@ -494,14 +646,28 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=100)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('facility_id', models.CharField(blank=True, max_length=50, null=True)),
                 ('status', models.CharField(default='active', max_length=50)),
                 ('serial', models.CharField(blank=True, max_length=50)),
                 ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
                 ('type', models.CharField(blank=True, max_length=50)),
                 ('width', models.PositiveSmallIntegerField(default=19)),
-                ('u_height', models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])),
+                (
+                    'u_height',
+                    models.PositiveSmallIntegerField(
+                        default=42,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(100),
+                        ],
+                    ),
+                ),
                 ('desc_units', models.BooleanField(default=False)),
                 ('outer_width', models.PositiveSmallIntegerField(blank=True, null=True)),
                 ('outer_depth', models.PositiveSmallIntegerField(blank=True, null=True)),
@@ -519,7 +685,10 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
-                ('units', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None)),
+                (
+                    'units',
+                    django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None),
+                ),
                 ('description', models.CharField(max_length=200)),
             ],
             options={
@@ -550,13 +719,27 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
                 ('mark_connected', models.BooleanField(default=False)),
                 ('type', models.CharField(max_length=50)),
-                ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+                (
+                    'positions',
+                    models.PositiveSmallIntegerField(
+                        default=1,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(1024),
+                        ],
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device', '_name'),
@@ -569,11 +752,25 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('type', models.CharField(max_length=50)),
-                ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+                (
+                    'positions',
+                    models.PositiveSmallIntegerField(
+                        default=1,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(1024),
+                        ],
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device_type', '_name'),
@@ -606,7 +803,12 @@ class Migration(migrations.Migration):
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=CustomFieldJSONEncoder)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=100, unique=True)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('slug', models.SlugField(max_length=100, unique=True)),
                 ('status', models.CharField(default='active', max_length=50)),
                 ('facility', models.CharField(blank=True, max_length=50)),
@@ -654,7 +856,16 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
                 ('domain', models.CharField(blank=True, max_length=30)),
-                ('master', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.device')),
+                (
+                    'master',
+                    models.OneToOneField(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='vc_master_for',
+                        to='dcim.device',
+                    ),
+                ),
             ],
             options={
                 'verbose_name_plural': 'virtual chassis',

+ 227 - 46
netbox/dcim/migrations/0002_squashed.py

@@ -6,7 +6,6 @@ import taggit.managers
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0001_initial'),
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@@ -28,17 +27,35 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='sitegroup',
             name='parent',
-            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.sitegroup'),
+            field=mptt.fields.TreeForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='children',
+                to='dcim.sitegroup',
+            ),
         ),
         migrations.AddField(
             model_name='site',
             name='group',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.sitegroup'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='sites',
+                to='dcim.sitegroup',
+            ),
         ),
         migrations.AddField(
             model_name='site',
             name='region',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.region'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='sites',
+                to='dcim.region',
+            ),
         ),
         migrations.AddField(
             model_name='site',
@@ -48,32 +65,56 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='site',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='sites',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='region',
             name='parent',
-            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.region'),
+            field=mptt.fields.TreeForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='children',
+                to='dcim.region',
+            ),
         ),
         migrations.AddField(
             model_name='rearporttemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='rearport',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='rearport',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='rearport',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='rearport',
@@ -83,7 +124,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='rackreservation',
             name='rack',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'
+            ),
         ),
         migrations.AddField(
             model_name='rackreservation',
@@ -93,7 +136,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='rackreservation',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='rackreservations',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='rackreservation',
@@ -103,12 +152,24 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='rack',
             name='location',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='racks', to='dcim.location'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='racks',
+                to='dcim.location',
+            ),
         ),
         migrations.AddField(
             model_name='rack',
             name='role',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.rackrole'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='racks',
+                to='dcim.rackrole',
+            ),
         ),
         migrations.AddField(
             model_name='rack',
@@ -123,32 +184,52 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='rack',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='racks',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='powerporttemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
@@ -158,7 +239,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='powerpanel',
             name='location',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'
+            ),
         ),
         migrations.AddField(
             model_name='powerpanel',
@@ -173,37 +256,63 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='poweroutlettemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlettemplate',
             name='power_port',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlet_templates', to='dcim.powerporttemplate'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='poweroutlet_templates',
+                to='dcim.powerporttemplate',
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='power_port',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlets', to='dcim.powerport'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='poweroutlets',
+                to='dcim.powerport',
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
@@ -213,27 +322,45 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='powerfeed',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='powerfeed',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='powerfeed',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='powerfeed',
             name='power_panel',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.powerpanel'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.powerpanel'
+            ),
         ),
         migrations.AddField(
             model_name='powerfeed',
             name='rack',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.rack'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='powerfeeds',
+                to='dcim.rack',
+            ),
         ),
         migrations.AddField(
             model_name='powerfeed',
@@ -243,32 +370,60 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='platform',
             name='manufacturer',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='dcim.manufacturer'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='platforms',
+                to='dcim.manufacturer',
+            ),
         ),
         migrations.AddField(
             model_name='location',
             name='parent',
-            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.location'),
+            field=mptt.fields.TreeForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='children',
+                to='dcim.location',
+            ),
         ),
         migrations.AddField(
             model_name='location',
             name='site',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='dcim.site'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='dcim.site'
+            ),
         ),
         migrations.AddField(
             model_name='inventoryitem',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='inventoryitem',
             name='manufacturer',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.manufacturer'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='inventory_items',
+                to='dcim.manufacturer',
+            ),
         ),
         migrations.AddField(
             model_name='inventoryitem',
             name='parent',
-            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitem'),
+            field=mptt.fields.TreeForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='child_items',
+                to='dcim.inventoryitem',
+            ),
         ),
         migrations.AddField(
             model_name='inventoryitem',
@@ -278,36 +433,62 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interfacetemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='lag',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.interface'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='member_interfaces',
+                to='dcim.interface',
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='parent',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='dcim.interface'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='child_interfaces',
+                to='dcim.interface',
+            ),
         ),
     ]

+ 225 - 40
netbox/dcim/migrations/0003_squashed_0130.py

@@ -4,7 +4,6 @@ import taggit.managers
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0002_auto_20160622_1821'),
         ('virtualization', '0001_virtualization'),
@@ -160,37 +159,61 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='untagged_vlan',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces_as_untagged', to='ipam.vlan'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='interfaces_as_untagged',
+                to='ipam.vlan',
+            ),
         ),
         migrations.AddField(
             model_name='frontporttemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='frontporttemplate',
             name='rear_port',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.rearporttemplate'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='frontport_templates',
+                to='dcim.rearporttemplate',
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
             name='rear_port',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport'
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
@@ -200,7 +223,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='devicetype',
             name='manufacturer',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
@@ -210,17 +235,27 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='devicebaytemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='devicebay',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='devicebay',
             name='installed_device',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.device'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='parent_bay',
+                to='dcim.device',
+            ),
         ),
         migrations.AddField(
             model_name='devicebay',
@@ -230,47 +265,89 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='device',
             name='cluster',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.cluster'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='devices',
+                to='virtualization.cluster',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='device_role',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.devicerole'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.devicerole'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='location',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.location'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='devices',
+                to='dcim.location',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='platform',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='dcim.platform'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='devices',
+                to='dcim.platform',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='primary_ip4',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip4_for', to='ipam.ipaddress'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='primary_ip4_for',
+                to='ipam.ipaddress',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='primary_ip6',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip6_for', to='ipam.ipaddress'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='primary_ip6_for',
+                to='ipam.ipaddress',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='rack',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.rack'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='devices',
+                to='dcim.rack',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='site',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site'
+            ),
         ),
         migrations.AddField(
             model_name='device',
@@ -280,37 +357,63 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='device',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='devices',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='virtual_chassis',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.virtualchassis'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='members',
+                to='dcim.virtualchassis',
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverporttemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
@@ -320,27 +423,41 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='consoleporttemplate',
             name='device_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+            ),
         ),
         migrations.AddField(
             model_name='consoleport',
             name='_cable_peer_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='consoleport',
             name='_path',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'
+            ),
         ),
         migrations.AddField(
             model_name='consoleport',
             name='cable',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'
+            ),
         ),
         migrations.AddField(
             model_name='consoleport',
             name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='consoleport',
@@ -350,22 +467,34 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='cablepath',
             name='destination_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='cablepath',
             name='origin_type',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'
+            ),
         ),
         migrations.AddField(
             model_name='cable',
             name='_termination_a_device',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='cable',
             name='_termination_b_device',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'
+            ),
         ),
         migrations.AddField(
             model_name='cable',
@@ -375,12 +504,64 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='cable',
             name='termination_a_type',
-            field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                limit_choices_to=models.Q(
+                    models.Q(
+                        models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))),
+                        models.Q(
+                            ('app_label', 'dcim'),
+                            (
+                                'model__in',
+                                (
+                                    'consoleport',
+                                    'consoleserverport',
+                                    'frontport',
+                                    'interface',
+                                    'powerfeed',
+                                    'poweroutlet',
+                                    'powerport',
+                                    'rearport',
+                                ),
+                            ),
+                        ),
+                        _connector='OR',
+                    )
+                ),
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='cable',
             name='termination_b_type',
-            field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                limit_choices_to=models.Q(
+                    models.Q(
+                        models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))),
+                        models.Q(
+                            ('app_label', 'dcim'),
+                            (
+                                'model__in',
+                                (
+                                    'consoleport',
+                                    'consoleserverport',
+                                    'frontport',
+                                    'interface',
+                                    'powerfeed',
+                                    'poweroutlet',
+                                    'powerport',
+                                    'rearport',
+                                ),
+                            ),
+                        ),
+                        _connector='OR',
+                    )
+                ),
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AlterUniqueTogether(
             name='rearporttemplate',
@@ -456,7 +637,11 @@ class Migration(migrations.Migration):
         ),
         migrations.AlterUniqueTogether(
             name='device',
-            unique_together={('rack', 'position', 'face'), ('virtual_chassis', 'vc_position'), ('site', 'tenant', 'name')},
+            unique_together={
+                ('rack', 'position', 'face'),
+                ('virtual_chassis', 'vc_position'),
+                ('site', 'tenant', 'name'),
+            },
         ),
         migrations.AlterUniqueTogether(
             name='consoleserverporttemplate',

+ 470 - 66
netbox/dcim/migrations/0131_squashed_0159.py

@@ -10,7 +10,6 @@ import utilities.ordering
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('dcim', '0131_consoleport_speed'),
         ('dcim', '0132_cable_length'),
@@ -40,7 +39,7 @@ class Migration(migrations.Migration):
         ('dcim', '0156_location_status'),
         ('dcim', '0157_new_cabling_models'),
         ('dcim', '0158_populate_cable_terminations'),
-        ('dcim', '0159_populate_cable_paths')
+        ('dcim', '0159_populate_cable_paths'),
     ]
 
     dependencies = [
@@ -96,17 +95,35 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='bridge',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interface'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='bridge_interfaces',
+                to='dcim.interface',
+            ),
         ),
         migrations.AddField(
             model_name='location',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='locations',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='cable',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='cables', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='cables',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
@@ -148,7 +165,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='location',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'name'), name='dcim_location_name'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('site', 'name'), name='dcim_location_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='location',
@@ -156,7 +175,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='location',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('site', 'slug'), name='dcim_location_slug'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('site', 'slug'), name='dcim_location_slug'
+            ),
         ),
         migrations.AddConstraint(
             model_name='region',
@@ -164,7 +185,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='region',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_region_name'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('name',), name='dcim_region_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='region',
@@ -172,7 +195,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='region',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_region_slug'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('slug',), name='dcim_region_slug'
+            ),
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
@@ -180,7 +205,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('name',), name='dcim_sitegroup_name'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('name',), name='dcim_sitegroup_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
@@ -188,7 +215,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent', None)), fields=('slug',), name='dcim_sitegroup_slug'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent', None)), fields=('slug',), name='dcim_sitegroup_slug'
+            ),
         ),
         migrations.AddField(
             model_name='devicerole',
@@ -328,7 +357,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='tx_power',
-            field=models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)]),
+            field=models.PositiveSmallIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MaxValueValidator(127)]
+            ),
         ),
         migrations.AddField(
             model_name='interface',
@@ -338,7 +369,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='wireless_link',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wireless.wirelesslink'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='wireless.wirelesslink',
+            ),
         ),
         migrations.AddField(
             model_name='site',
@@ -348,12 +385,24 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='device',
             name='primary_ip4',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='ipam.ipaddress',
+            ),
         ),
         migrations.AlterField(
             model_name='device',
             name='primary_ip6',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='ipam.ipaddress',
+            ),
         ),
         migrations.RemoveField(
             model_name='site',
@@ -372,7 +421,23 @@ class Migration(migrations.Migration):
             name='contact_phone',
         ),
         migrations.RunSQL(
-            sql="\n            DO $$\n            DECLARE\n                idx record;\n            BEGIN\n                FOR idx IN\n                    SELECT indexname AS old_name,\n                           replace(indexname, 'module', 'inventoryitem') AS new_name\n                    FROM pg_indexes\n                    WHERE schemaname = 'public' AND\n                          tablename = 'dcim_inventoryitem' AND\n                          indexname LIKE 'dcim_module_%'\n                LOOP\n                    EXECUTE format(\n                        'ALTER INDEX %I RENAME TO %I;',\n                        idx.old_name,\n                        idx.new_name\n                    );\n                END LOOP;\n            END$$;\n            ",
+            sql="""DO $$
+            DECLARE idx record;
+            BEGIN
+                FOR idx IN
+                    SELECT indexname AS old_name, replace(indexname, 'module', 'inventoryitem') AS new_name
+                    FROM pg_indexes
+                    WHERE schemaname = 'public' AND
+                          tablename = 'dcim_inventoryitem' AND
+                          indexname LIKE 'dcim_module_%'
+                LOOP
+                    EXECUTE format(
+                        'ALTER INDEX %I RENAME TO %I;',
+                        idx.old_name,
+                        idx.new_name
+                    );
+                END LOOP;
+            END$$;""",
         ),
         migrations.AlterModelOptions(
             name='consoleporttemplate',
@@ -405,49 +470,99 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='consoleporttemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='consoleserverporttemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='frontporttemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='interfacetemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='poweroutlettemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='powerporttemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AlterField(
             model_name='rearporttemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.CreateModel(
             name='ModuleType',
             fields=[
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('model', models.CharField(max_length=100)),
                 ('part_number', models.CharField(blank=True, max_length=50)),
                 ('comments', models.TextField(blank=True)),
-                ('manufacturer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='module_types', to='dcim.manufacturer')),
+                (
+                    'manufacturer',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='module_types', to='dcim.manufacturer'
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],
             options={
@@ -460,14 +575,27 @@ class Migration(migrations.Migration):
             fields=[
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('position', models.CharField(blank=True, max_length=30)),
                 ('description', models.CharField(blank=True, max_length=200)),
-                ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device')),
+                (
+                    'device',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.device'
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],
             options={
@@ -480,15 +608,35 @@ class Migration(migrations.Migration):
             fields=[
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('local_context_data', models.JSONField(blank=True, null=True)),
                 ('serial', models.CharField(blank=True, max_length=50)),
                 ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
                 ('comments', models.TextField(blank=True)),
-                ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='dcim.device')),
-                ('module_bay', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='installed_module', to='dcim.modulebay')),
-                ('module_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.moduletype')),
+                (
+                    'device',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='dcim.device'
+                    ),
+                ),
+                (
+                    'module_bay',
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='installed_module',
+                        to='dcim.modulebay',
+                    ),
+                ),
+                (
+                    'module_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.moduletype'
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],
             options={
@@ -498,72 +646,156 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='consoleport',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='consoleporttemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverport',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='consoleserverporttemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='frontport',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='frontporttemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='interfacetemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlet',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='poweroutlettemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='powerport',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='powerporttemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AddField(
             model_name='rearport',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='rearporttemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AlterUniqueTogether(
             name='consoleporttemplate',
@@ -598,7 +830,10 @@ class Migration(migrations.Migration):
             fields=[
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=100, unique=True)),
                 ('slug', models.SlugField(max_length=100, unique=True)),
@@ -613,7 +848,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='inventoryitem',
             name='role',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.inventoryitemrole'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='inventory_items',
+                to='dcim.inventoryitemrole',
+            ),
         ),
         migrations.AddField(
             model_name='inventoryitem',
@@ -623,12 +864,39 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='inventoryitem',
             name='component_type',
-            field=models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'poweroutlet', 'powerport', 'rearport'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True,
+                limit_choices_to=models.Q(
+                    ('app_label', 'dcim'),
+                    (
+                        'model__in',
+                        (
+                            'consoleport',
+                            'consoleserverport',
+                            'frontport',
+                            'interface',
+                            'poweroutlet',
+                            'powerport',
+                            'rearport',
+                        ),
+                    ),
+                ),
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='+',
+                to='contenttypes.contenttype',
+            ),
         ),
         migrations.AddField(
             model_name='interface',
             name='vrf',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces', to='ipam.vrf'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='interfaces',
+                to='ipam.vrf',
+            ),
         ),
         migrations.AddField(
             model_name='interface',
@@ -952,7 +1220,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('component_id', models.PositiveBigIntegerField(blank=True, null=True)),
@@ -961,11 +1234,67 @@ class Migration(migrations.Migration):
                 ('rght', models.PositiveIntegerField(editable=False)),
                 ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
                 ('level', models.PositiveIntegerField(editable=False)),
-                ('component_type', models.ForeignKey(blank=True, limit_choices_to=models.Q(('app_label', 'dcim'), ('model__in', ('consoleporttemplate', 'consoleserverporttemplate', 'frontporttemplate', 'interfacetemplate', 'poweroutlettemplate', 'powerporttemplate', 'rearporttemplate'))), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                ('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype')),
-                ('manufacturer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.manufacturer')),
-                ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitemtemplate')),
-                ('role', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_item_templates', to='dcim.inventoryitemrole')),
+                (
+                    'component_type',
+                    models.ForeignKey(
+                        blank=True,
+                        limit_choices_to=models.Q(
+                            ('app_label', 'dcim'),
+                            (
+                                'model__in',
+                                (
+                                    'consoleporttemplate',
+                                    'consoleserverporttemplate',
+                                    'frontporttemplate',
+                                    'interfacetemplate',
+                                    'poweroutlettemplate',
+                                    'powerporttemplate',
+                                    'rearporttemplate',
+                                ),
+                            ),
+                        ),
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
+                (
+                    'device_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+                    ),
+                ),
+                (
+                    'manufacturer',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='inventory_item_templates',
+                        to='dcim.manufacturer',
+                    ),
+                ),
+                (
+                    'parent',
+                    mptt.fields.TreeForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='child_items',
+                        to='dcim.inventoryitemtemplate',
+                    ),
+                ),
+                (
+                    'role',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='inventory_item_templates',
+                        to='dcim.inventoryitemrole',
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device_type__id', 'parent__id', '_name'),
@@ -989,11 +1318,21 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=64)),
-                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                (
+                    '_name',
+                    utilities.fields.NaturalOrderingField(
+                        'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize
+                    ),
+                ),
                 ('label', models.CharField(blank=True, max_length=64)),
                 ('position', models.CharField(blank=True, max_length=30)),
                 ('description', models.CharField(blank=True, max_length=200)),
-                ('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype')),
+                (
+                    'device_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'
+                    ),
+                ),
             ],
             options={
                 'ordering': ('device_type', '_name'),
@@ -1088,7 +1427,16 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='device',
             name='position',
-            field=models.DecimalField(blank=True, decimal_places=1, max_digits=4, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100.5)]),
+            field=models.DecimalField(
+                blank=True,
+                decimal_places=1,
+                max_digits=4,
+                null=True,
+                validators=[
+                    django.core.validators.MinValueValidator(1),
+                    django.core.validators.MaxValueValidator(100.5),
+                ],
+            ),
         ),
         migrations.AddField(
             model_name='interface',
@@ -1121,12 +1469,66 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('cable_end', models.CharField(max_length=1)),
                 ('termination_id', models.PositiveBigIntegerField()),
-                ('cable', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='dcim.cable')),
-                ('termination_type', models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                ('_device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.device')),
-                ('_rack', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.rack')),
-                ('_location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location')),
-                ('_site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.site')),
+                (
+                    'cable',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='dcim.cable'
+                    ),
+                ),
+                (
+                    'termination_type',
+                    models.ForeignKey(
+                        limit_choices_to=models.Q(
+                            models.Q(
+                                models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))),
+                                models.Q(
+                                    ('app_label', 'dcim'),
+                                    (
+                                        'model__in',
+                                        (
+                                            'consoleport',
+                                            'consoleserverport',
+                                            'frontport',
+                                            'interface',
+                                            'powerfeed',
+                                            'poweroutlet',
+                                            'powerport',
+                                            'rearport',
+                                        ),
+                                    ),
+                                ),
+                                _connector='OR',
+                            )
+                        ),
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
+                (
+                    '_device',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.device'
+                    ),
+                ),
+                (
+                    '_rack',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.rack'
+                    ),
+                ),
+                (
+                    '_location',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.location'
+                    ),
+                ),
+                (
+                    '_site',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='dcim.site'
+                    ),
+                ),
             ],
             options={
                 'ordering': ('cable', 'cable_end', 'pk'),
@@ -1134,7 +1536,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='cabletermination',
-            constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cable_termination_unique_termination'),
+            constraint=models.UniqueConstraint(
+                fields=('termination_type', 'termination_id'), name='dcim_cable_termination_unique_termination'
+            ),
         ),
         migrations.RenameField(
             model_name='cablepath',

+ 185 - 45
netbox/dcim/migrations/0160_squashed_0166.py

@@ -6,7 +6,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('dcim', '0160_populate_cable_ends'),
         ('dcim', '0161_cabling_cleanup'),
@@ -14,7 +13,7 @@ class Migration(migrations.Migration):
         ('dcim', '0163_weight_fields'),
         ('dcim', '0164_rack_mounting_depth'),
         ('dcim', '0165_standardize_description_comments'),
-        ('dcim', '0166_virtualdevicecontext')
+        ('dcim', '0166_virtualdevicecontext'),
     ]
 
     dependencies = [
@@ -275,7 +274,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='cabletermination',
-            constraint=models.UniqueConstraint(fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination'),
+            constraint=models.UniqueConstraint(
+                fields=('termination_type', 'termination_id'), name='dcim_cabletermination_unique_termination'
+            ),
         ),
         migrations.AddConstraint(
             model_name='consoleport',
@@ -283,39 +284,64 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='consoleporttemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleporttemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_consoleporttemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='consoleporttemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleporttemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_consoleporttemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='consoleserverport',
-            constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleserverport_unique_device_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device', 'name'), name='dcim_consoleserverport_unique_device_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='consoleserverporttemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_consoleserverporttemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_consoleserverporttemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='consoleserverporttemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_consoleserverporttemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_consoleserverporttemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='device',
-            constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), models.F('tenant'), name='dcim_device_unique_name_site_tenant'),
+            constraint=models.UniqueConstraint(
+                django.db.models.functions.text.Lower('name'),
+                models.F('site'),
+                models.F('tenant'),
+                name='dcim_device_unique_name_site_tenant',
+            ),
         ),
         migrations.AddConstraint(
             model_name='device',
-            constraint=models.UniqueConstraint(django.db.models.functions.text.Lower('name'), models.F('site'), condition=models.Q(('tenant__isnull', True)), name='dcim_device_unique_name_site', violation_error_message='Device name must be unique per site.'),
+            constraint=models.UniqueConstraint(
+                django.db.models.functions.text.Lower('name'),
+                models.F('site'),
+                condition=models.Q(('tenant__isnull', True)),
+                name='dcim_device_unique_name_site',
+                violation_error_message='Device name must be unique per site.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='device',
-            constraint=models.UniqueConstraint(fields=('rack', 'position', 'face'), name='dcim_device_unique_rack_position_face'),
+            constraint=models.UniqueConstraint(
+                fields=('rack', 'position', 'face'), name='dcim_device_unique_rack_position_face'
+            ),
         ),
         migrations.AddConstraint(
             model_name='device',
-            constraint=models.UniqueConstraint(fields=('virtual_chassis', 'vc_position'), name='dcim_device_unique_virtual_chassis_vc_position'),
+            constraint=models.UniqueConstraint(
+                fields=('virtual_chassis', 'vc_position'), name='dcim_device_unique_virtual_chassis_vc_position'
+            ),
         ),
         migrations.AddConstraint(
             model_name='devicebay',
@@ -323,15 +349,21 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='devicebaytemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_devicebaytemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_devicebaytemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='devicetype',
-            constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_devicetype_unique_manufacturer_model'),
+            constraint=models.UniqueConstraint(
+                fields=('manufacturer', 'model'), name='dcim_devicetype_unique_manufacturer_model'
+            ),
         ),
         migrations.AddConstraint(
             model_name='devicetype',
-            constraint=models.UniqueConstraint(fields=('manufacturer', 'slug'), name='dcim_devicetype_unique_manufacturer_slug'),
+            constraint=models.UniqueConstraint(
+                fields=('manufacturer', 'slug'), name='dcim_devicetype_unique_manufacturer_slug'
+            ),
         ),
         migrations.AddConstraint(
             model_name='frontport',
@@ -339,19 +371,27 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='frontport',
-            constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontport_unique_rear_port_position'),
+            constraint=models.UniqueConstraint(
+                fields=('rear_port', 'rear_port_position'), name='dcim_frontport_unique_rear_port_position'
+            ),
         ),
         migrations.AddConstraint(
             model_name='frontporttemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_frontporttemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_frontporttemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='frontporttemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_frontporttemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_frontporttemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='frontporttemplate',
-            constraint=models.UniqueConstraint(fields=('rear_port', 'rear_port_position'), name='dcim_frontporttemplate_unique_rear_port_position'),
+            constraint=models.UniqueConstraint(
+                fields=('rear_port', 'rear_port_position'), name='dcim_frontporttemplate_unique_rear_port_position'
+            ),
         ),
         migrations.AddConstraint(
             model_name='interface',
@@ -359,27 +399,46 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='interfacetemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_interfacetemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_interfacetemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='interfacetemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_interfacetemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_interfacetemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='inventoryitem',
-            constraint=models.UniqueConstraint(fields=('device', 'parent', 'name'), name='dcim_inventoryitem_unique_device_parent_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device', 'parent', 'name'), name='dcim_inventoryitem_unique_device_parent_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='inventoryitemtemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'parent', 'name'), name='dcim_inventoryitemtemplate_unique_device_type_parent_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'parent', 'name'),
+                name='dcim_inventoryitemtemplate_unique_device_type_parent_name',
+            ),
         ),
         migrations.AddConstraint(
             model_name='location',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'name'), name='dcim_location_name', violation_error_message='A location with this name already exists within the specified site.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('site', 'name'),
+                name='dcim_location_name',
+                violation_error_message='A location with this name already exists within the specified site.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='location',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('site', 'slug'), name='dcim_location_slug', violation_error_message='A location with this slug already exists within the specified site.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('site', 'slug'),
+                name='dcim_location_slug',
+                violation_error_message='A location with this slug already exists within the specified site.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='modulebay',
@@ -387,15 +446,21 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='modulebaytemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_modulebaytemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_modulebaytemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='moduletype',
-            constraint=models.UniqueConstraint(fields=('manufacturer', 'model'), name='dcim_moduletype_unique_manufacturer_model'),
+            constraint=models.UniqueConstraint(
+                fields=('manufacturer', 'model'), name='dcim_moduletype_unique_manufacturer_model'
+            ),
         ),
         migrations.AddConstraint(
             model_name='powerfeed',
-            constraint=models.UniqueConstraint(fields=('power_panel', 'name'), name='dcim_powerfeed_unique_power_panel_name'),
+            constraint=models.UniqueConstraint(
+                fields=('power_panel', 'name'), name='dcim_powerfeed_unique_power_panel_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='poweroutlet',
@@ -403,11 +468,15 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='poweroutlettemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_poweroutlettemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_poweroutlettemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='poweroutlettemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_poweroutlettemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_poweroutlettemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='powerpanel',
@@ -419,11 +488,15 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='powerporttemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_powerporttemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_powerporttemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='powerporttemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_powerporttemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_powerporttemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='rack',
@@ -431,7 +504,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='rack',
-            constraint=models.UniqueConstraint(fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id'),
+            constraint=models.UniqueConstraint(
+                fields=('location', 'facility_id'), name='dcim_rack_unique_location_facility_id'
+            ),
         ),
         migrations.AddConstraint(
             model_name='rearport',
@@ -439,27 +514,51 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='rearporttemplate',
-            constraint=models.UniqueConstraint(fields=('device_type', 'name'), name='dcim_rearporttemplate_unique_device_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device_type', 'name'), name='dcim_rearporttemplate_unique_device_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='rearporttemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_rearporttemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_rearporttemplate_unique_module_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='region',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_region_name', violation_error_message='A top-level region with this name already exists.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('name',),
+                name='dcim_region_name',
+                violation_error_message='A top-level region with this name already exists.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='region',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_region_slug', violation_error_message='A top-level region with this slug already exists.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('slug',),
+                name='dcim_region_slug',
+                violation_error_message='A top-level region with this slug already exists.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('name',), name='dcim_sitegroup_name', violation_error_message='A top-level site group with this name already exists.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('name',),
+                name='dcim_sitegroup_name',
+                violation_error_message='A top-level site group with this name already exists.',
+            ),
         ),
         migrations.AddConstraint(
             model_name='sitegroup',
-            constraint=models.UniqueConstraint(condition=models.Q(('parent__isnull', True)), fields=('slug',), name='dcim_sitegroup_slug', violation_error_message='A top-level site group with this slug already exists.'),
+            constraint=models.UniqueConstraint(
+                condition=models.Q(('parent__isnull', True)),
+                fields=('slug',),
+                name='dcim_sitegroup_slug',
+                violation_error_message='A top-level site group with this slug already exists.',
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
@@ -592,17 +691,56 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('name', models.CharField(max_length=64)),
                 ('status', models.CharField(max_length=50)),
                 ('identifier', models.PositiveSmallIntegerField(blank=True, null=True)),
                 ('comments', models.TextField(blank=True)),
-                ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='dcim.device')),
-                ('primary_ip4', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')),
-                ('primary_ip6', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')),
+                (
+                    'device',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='vdcs',
+                        to='dcim.device',
+                    ),
+                ),
+                (
+                    'primary_ip4',
+                    models.OneToOneField(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to='ipam.ipaddress',
+                    ),
+                ),
+                (
+                    'primary_ip6',
+                    models.OneToOneField(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to='ipam.ipaddress',
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
-                ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='tenancy.tenant')),
+                (
+                    'tenant',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='vdcs',
+                        to='tenancy.tenant',
+                    ),
+                ),
             ],
             options={
                 'ordering': ['name'],
@@ -615,7 +753,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='virtualdevicecontext',
-            constraint=models.UniqueConstraint(fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier'),
+            constraint=models.UniqueConstraint(
+                fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifier'
+            ),
         ),
         migrations.AddConstraint(
             model_name='virtualdevicecontext',

+ 125 - 34
netbox/dcim/migrations/0167_squashed_0182.py

@@ -6,7 +6,6 @@ import utilities.fields
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('dcim', '0167_module_status'),
         ('dcim', '0168_interface_template_enabled'),
@@ -24,7 +23,7 @@ class Migration(migrations.Migration):
         ('dcim', '0179_interfacetemplate_rf_role'),
         ('dcim', '0180_powerfeed_tenant'),
         ('dcim', '0181_rename_device_role_device_role'),
-        ('dcim', '0182_zero_length_cable_fix')
+        ('dcim', '0182_zero_length_cable_fix'),
     ]
 
     dependencies = [
@@ -48,27 +47,57 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interfacetemplate',
             name='bridge',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bridge_interfaces', to='dcim.interfacetemplate'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='bridge_interfaces',
+                to='dcim.interfacetemplate',
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='default_platform',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.platform'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='dcim.platform',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='config_template',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='%(class)ss', to='extras.configtemplate'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='%(class)ss',
+                to='extras.configtemplate',
+            ),
         ),
         migrations.AddField(
             model_name='devicerole',
             name='config_template',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='device_roles', to='extras.configtemplate'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='device_roles',
+                to='extras.configtemplate',
+            ),
         ),
         migrations.AddField(
             model_name='platform',
             name='config_template',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='extras.configtemplate'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='platforms',
+                to='extras.configtemplate',
+            ),
         ),
         migrations.AddField(
             model_name='cabletermination',
@@ -83,22 +112,30 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='powerport',
             name='allocated_draw',
-            field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]),
+            field=models.PositiveIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+            ),
         ),
         migrations.AlterField(
             model_name='powerport',
             name='maximum_draw',
-            field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]),
+            field=models.PositiveIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+            ),
         ),
         migrations.AlterField(
             model_name='powerporttemplate',
             name='allocated_draw',
-            field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]),
+            field=models.PositiveIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+            ),
         ),
         migrations.AlterField(
             model_name='powerporttemplate',
             name='maximum_draw',
-            field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]),
+            field=models.PositiveIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+            ),
         ),
         migrations.RemoveField(
             model_name='platform',
@@ -126,112 +163,160 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='device',
             name='oob_ip',
-            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'),
+            field=models.OneToOneField(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='ipam.ipaddress',
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='console_port_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsolePort'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.ConsolePort'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='console_server_port_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ConsoleServerPort'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.ConsoleServerPort'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='power_port_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerPort'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.PowerPort'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='power_outlet_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.PowerOutlet'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.PowerOutlet'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='interface_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.Interface'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.Interface'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='front_port_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.FrontPort'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.FrontPort'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='rear_port_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.RearPort'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.RearPort'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='device_bay_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.DeviceBay'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.DeviceBay'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='module_bay_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.ModuleBay'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.ModuleBay'
+            ),
         ),
         migrations.AddField(
             model_name='device',
             name='inventory_item_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device', to_model='dcim.InventoryItem'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device', to_model='dcim.InventoryItem'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='console_port_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ConsolePortTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.ConsolePortTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='console_server_port_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.ConsoleServerPortTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='power_port_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerPortTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.PowerPortTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='power_outlet_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.PowerOutletTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.PowerOutletTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='interface_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InterfaceTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.InterfaceTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='front_port_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.FrontPortTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.FrontPortTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='rear_port_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.RearPortTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.RearPortTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='device_bay_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.DeviceBayTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.DeviceBayTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='module_bay_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.ModuleBayTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.ModuleBayTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='devicetype',
             name='inventory_item_template_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='device_type', to_model='dcim.InventoryItemTemplate'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='device_type', to_model='dcim.InventoryItemTemplate'
+            ),
         ),
         migrations.AddField(
             model_name='virtualchassis',
             name='member_count',
-            field=utilities.fields.CounterCacheField(default=0, editable=False, to_field='virtual_chassis', to_model='dcim.Device'),
+            field=utilities.fields.CounterCacheField(
+                default=0, editable=False, to_field='virtual_chassis', to_model='dcim.Device'
+            ),
         ),
         migrations.AddField(
             model_name='interfacetemplate',
@@ -241,7 +326,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='powerfeed',
             name='tenant',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='power_feeds', to='tenancy.tenant'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='power_feeds',
+                to='tenancy.tenant',
+            ),
         ),
         migrations.RenameField(
             model_name='device',

+ 7 - 2
netbox/dcim/migrations/0184_protect_child_interfaces.py

@@ -5,7 +5,6 @@ import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0183_devicetype_exclude_from_utilization'),
     ]
@@ -14,6 +13,12 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='interface',
             name='parent',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='child_interfaces', to='dcim.interface'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.RESTRICT,
+                related_name='child_interfaces',
+                to='dcim.interface',
+            ),
         ),
     ]

+ 0 - 1
netbox/dcim/migrations/0185_gfk_indexes.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0184_protect_child_interfaces'),
     ]

+ 0 - 1
netbox/dcim/migrations/0186_location_facility.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0185_gfk_indexes'),
     ]

+ 0 - 1
netbox/dcim/migrations/0187_alter_device_vc_position.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0186_location_facility'),
     ]

+ 26 - 22
netbox/dcim/migrations/0188_racktype.py

@@ -9,7 +9,6 @@ import utilities.ordering
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0118_customfield_uniqueness'),
         ('dcim', '0187_alter_device_vc_position'),
@@ -22,36 +21,41 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(
-                    blank=True,
-                    default=dict,
-                    encoder=utilities.json.CustomFieldJSONEncoder
-                )),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('weight', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True)),
                 ('weight_unit', models.CharField(blank=True, max_length=50)),
                 ('_abs_weight', models.PositiveBigIntegerField(blank=True, null=True)),
-                ('manufacturer', models.ForeignKey(
-                    on_delete=django.db.models.deletion.PROTECT,
-                    related_name='rack_types',
-                    to='dcim.manufacturer'
-                )),
+                (
+                    'manufacturer',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='rack_types', to='dcim.manufacturer'
+                    ),
+                ),
                 ('model', models.CharField(max_length=100)),
                 ('slug', models.SlugField(max_length=100, unique=True)),
                 ('form_factor', models.CharField(max_length=50)),
                 ('width', models.PositiveSmallIntegerField(default=19)),
-                ('u_height', models.PositiveSmallIntegerField(
-                    default=42,
-                    validators=[
-                        django.core.validators.MinValueValidator(1),
-                        django.core.validators.MaxValueValidator(100),
-                    ]
-                )),
-                ('starting_unit', models.PositiveSmallIntegerField(
-                    default=1,
-                    validators=[django.core.validators.MinValueValidator(1)]
-                )),
+                (
+                    'u_height',
+                    models.PositiveSmallIntegerField(
+                        default=42,
+                        validators=[
+                            django.core.validators.MinValueValidator(1),
+                            django.core.validators.MaxValueValidator(100),
+                        ],
+                    ),
+                ),
+                (
+                    'starting_unit',
+                    models.PositiveSmallIntegerField(
+                        default=1, validators=[django.core.validators.MinValueValidator(1)]
+                    ),
+                ),
                 ('desc_units', models.BooleanField(default=False)),
                 ('outer_width', models.PositiveSmallIntegerField(blank=True, null=True)),
                 ('outer_depth', models.PositiveSmallIntegerField(blank=True, null=True)),

+ 0 - 1
netbox/dcim/migrations/0189_moduletype_rack_airflow.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0188_racktype'),
     ]

+ 35 - 7
netbox/dcim/migrations/0190_nested_modules.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0189_moduletype_rack_airflow'),
         ('extras', '0121_customfield_related_object_filter'),
@@ -34,12 +33,25 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='modulebay',
             name='module',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.module'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.module',
+            ),
         ),
         migrations.AddField(
             model_name='modulebay',
             name='parent',
-            field=mptt.fields.TreeForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.modulebay'),
+            field=mptt.fields.TreeForeignKey(
+                blank=True,
+                editable=False,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='children',
+                to='dcim.modulebay',
+            ),
         ),
         migrations.AddField(
             model_name='modulebay',
@@ -56,19 +68,35 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='modulebaytemplate',
             name='module_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.moduletype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.moduletype',
+            ),
         ),
         migrations.AlterField(
             model_name='modulebaytemplate',
             name='device_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='dcim.devicetype'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name='%(class)ss',
+                to='dcim.devicetype',
+            ),
         ),
         migrations.AddConstraint(
             model_name='modulebay',
-            constraint=models.UniqueConstraint(fields=('device', 'module', 'name'), name='dcim_modulebay_unique_device_module_name'),
+            constraint=models.UniqueConstraint(
+                fields=('device', 'module', 'name'), name='dcim_modulebay_unique_device_module_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='modulebaytemplate',
-            constraint=models.UniqueConstraint(fields=('module_type', 'name'), name='dcim_modulebaytemplate_unique_module_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('module_type', 'name'), name='dcim_modulebaytemplate_unique_module_type_name'
+            ),
         ),
     ]

+ 1 - 5
netbox/dcim/migrations/0191_module_bay_rebuild.py

@@ -13,14 +13,10 @@ def rebuild_mptt(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0190_nested_modules'),
     ]
 
     operations = [
-        migrations.RunPython(
-            code=rebuild_mptt,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=rebuild_mptt, reverse_code=migrations.RunPython.noop),
     ]

+ 0 - 1
netbox/dcim/migrations/0192_inventoryitem_status.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0191_module_bay_rebuild'),
     ]

+ 0 - 1
netbox/dcim/migrations/0193_poweroutlet_color.py

@@ -5,7 +5,6 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0192_inventoryitem_status'),
     ]

+ 1 - 5
netbox/dcim/migrations/0194_charfield_null_choices.py

@@ -69,7 +69,6 @@ def set_null_values(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0193_poweroutlet_color'),
     ]
@@ -280,8 +279,5 @@ class Migration(migrations.Migration):
             name='cable_end',
             field=models.CharField(blank=True, max_length=1, null=True),
         ),
-        migrations.RunPython(
-            code=set_null_values,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=set_null_values, reverse_code=migrations.RunPython.noop),
     ]

+ 3 - 2
netbox/dcim/migrations/0195_interface_vlan_translation_policy.py

@@ -5,7 +5,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0194_charfield_null_choices'),
         ('ipam', '0074_vlantranslationpolicy_vlantranslationrule'),
@@ -15,6 +14,8 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='vlan_translation_policy',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='ipam.vlantranslationpolicy'
+            ),
         ),
     ]

+ 14 - 3
netbox/dcim/migrations/0196_qinq_svlan.py

@@ -3,7 +3,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0195_interface_vlan_translation_policy'),
         ('ipam', '0075_vlan_qinq'),
@@ -13,7 +12,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='interface',
             name='qinq_svlan',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_svlan', to='ipam.vlan'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='%(class)ss_svlan',
+                to='ipam.vlan',
+            ),
         ),
         migrations.AlterField(
             model_name='interface',
@@ -23,6 +28,12 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='interface',
             name='untagged_vlan',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='%(class)ss_as_untagged', to='ipam.vlan'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='%(class)ss_as_untagged',
+                to='ipam.vlan',
+            ),
         ),
     ]

+ 3 - 4
netbox/dcim/migrations/0197_natural_sort_collation.py

@@ -3,15 +3,14 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0196_qinq_svlan'),
     ]
 
     operations = [
         CreateCollation(
-            "natural_sort",
-            provider="icu",
-            locale="und-u-kn-true",
+            'natural_sort',
+            provider='icu',
+            locale='und-u-kn-true',
         ),
     ]

+ 0 - 1
netbox/dcim/migrations/0198_natural_ordering.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0197_natural_sort_collation'),
     ]

+ 22 - 7
netbox/dcim/migrations/0199_macaddress.py

@@ -7,7 +7,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0198_natural_ordering'),
         ('extras', '0122_charfield_null_choices'),
@@ -20,17 +19,33 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
-                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
+                (
+                    'custom_field_data',
+                    models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder),
+                ),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('comments', models.TextField(blank=True)),
                 ('mac_address', dcim.fields.MACAddressField()),
                 ('assigned_object_id', models.PositiveBigIntegerField(blank=True, null=True)),
-                ('assigned_object_type', models.ForeignKey(blank=True, limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
+                (
+                    'assigned_object_type',
+                    models.ForeignKey(
+                        blank=True,
+                        limit_choices_to=models.Q(
+                            models.Q(
+                                models.Q(('app_label', 'dcim'), ('model', 'interface')),
+                                models.Q(('app_label', 'virtualization'), ('model', 'vminterface')),
+                                _connector='OR',
+                            )
+                        ),
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],
-            options={
-                'abstract': False,
-                'ordering': ('mac_address',)
-            },
+            options={'abstract': False, 'ordering': ('mac_address',)},
         ),
     ]

+ 3 - 9
netbox/dcim/migrations/0200_populate_mac_addresses.py

@@ -10,9 +10,7 @@ def populate_mac_addresses(apps, schema_editor):
 
     mac_addresses = [
         MACAddress(
-            mac_address=interface.mac_address,
-            assigned_object_type=interface_ct,
-            assigned_object_id=interface.pk
+            mac_address=interface.mac_address, assigned_object_type=interface_ct, assigned_object_id=interface.pk
         )
         for interface in Interface.objects.filter(mac_address__isnull=False)
     ]
@@ -24,7 +22,6 @@ def populate_mac_addresses(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0199_macaddress'),
     ]
@@ -38,13 +35,10 @@ class Migration(migrations.Migration):
                 null=True,
                 on_delete=django.db.models.deletion.SET_NULL,
                 related_name='+',
-                to='dcim.macaddress'
+                to='dcim.macaddress',
             ),
         ),
-        migrations.RunPython(
-            code=populate_mac_addresses,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=populate_mac_addresses, reverse_code=migrations.RunPython.noop),
         migrations.RemoveField(
             model_name='interface',
             name='mac_address',

+ 18 - 6
netbox/dcim/models/device_component_templates.py

@@ -311,7 +311,9 @@ class PowerPortTemplate(ModularComponentTemplateModel):
         if self.maximum_draw is not None and self.allocated_draw is not None:
             if self.allocated_draw > self.maximum_draw:
                 raise ValidationError({
-                    'allocated_draw': _("Allocated draw cannot exceed the maximum draw ({maximum_draw}W).").format(maximum_draw=self.maximum_draw)
+                    'allocated_draw': _(
+                        "Allocated draw cannot exceed the maximum draw ({maximum_draw}W)."
+                    ).format(maximum_draw=self.maximum_draw)
                 })
 
     def to_yaml(self):
@@ -365,11 +367,15 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
         if self.power_port:
             if self.device_type and self.power_port.device_type != self.device_type:
                 raise ValidationError(
-                    _("Parent power port ({power_port}) must belong to the same device type").format(power_port=self.power_port)
+                    _("Parent power port ({power_port}) must belong to the same device type").format(
+                        power_port=self.power_port
+                    )
                 )
             if self.module_type and self.power_port.module_type != self.module_type:
                 raise ValidationError(
-                    _("Parent power port ({power_port}) must belong to the same module type").format(power_port=self.power_port)
+                    _("Parent power port ({power_port}) must belong to the same module type").format(
+                        power_port=self.power_port
+                    )
                 )
 
     def instantiate(self, **kwargs):
@@ -467,11 +473,15 @@ class InterfaceTemplate(ModularComponentTemplateModel):
                 raise ValidationError({'bridge': _("An interface cannot be bridged to itself.")})
             if self.device_type and self.device_type != self.bridge.device_type:
                 raise ValidationError({
-                    'bridge': _("Bridge interface ({bridge}) must belong to the same device type").format(bridge=self.bridge)
+                    'bridge': _(
+                        "Bridge interface ({bridge}) must belong to the same device type"
+                    ).format(bridge=self.bridge)
                 })
             if self.module_type and self.module_type != self.bridge.module_type:
                 raise ValidationError({
-                    'bridge': _("Bridge interface ({bridge}) must belong to the same module type").format(bridge=self.bridge)
+                    'bridge': _(
+                        "Bridge interface ({bridge}) must belong to the same module type"
+                    ).format(bridge=self.bridge)
                 })
 
         if self.rf_role and self.type not in WIRELESS_IFACE_TYPES:
@@ -714,7 +724,9 @@ class DeviceBayTemplate(ComponentTemplateModel):
     def clean(self):
         if self.device_type and self.device_type.subdevice_role != SubdeviceRoleChoices.ROLE_PARENT:
             raise ValidationError(
-                _("Subdevice role of device type ({device_type}) must be set to \"parent\" to allow device bays.").format(device_type=self.device_type)
+                _(
+                    'Subdevice role of device type ({device_type}) must be set to "parent" to allow device bays.'
+                ).format(device_type=self.device_type)
             )
 
     def to_yaml(self):

+ 16 - 6
netbox/dcim/models/devices.py

@@ -532,7 +532,10 @@ def update_interface_bridges(device, interface_templates, module=None):
         interface = Interface.objects.get(device=device, name=interface_template.resolve_name(module=module))
 
         if interface_template.bridge:
-            interface.bridge = Interface.objects.get(device=device, name=interface_template.bridge.resolve_name(module=module))
+            interface.bridge = Interface.objects.get(
+                device=device,
+                name=interface_template.bridge.resolve_name(module=module)
+            )
             interface.full_clean()
             interface.save()
 
@@ -909,7 +912,10 @@ class Device(
                 })
             if self.primary_ip4.assigned_object in vc_interfaces:
                 pass
-            elif self.primary_ip4.nat_inside is not None and self.primary_ip4.nat_inside.assigned_object in vc_interfaces:
+            elif (
+                    self.primary_ip4.nat_inside is not None and
+                    self.primary_ip4.nat_inside.assigned_object in vc_interfaces
+            ):
                 pass
             else:
                 raise ValidationError({
@@ -924,7 +930,10 @@ class Device(
                 })
             if self.primary_ip6.assigned_object in vc_interfaces:
                 pass
-            elif self.primary_ip6.nat_inside is not None and self.primary_ip6.nat_inside.assigned_object in vc_interfaces:
+            elif (
+                    self.primary_ip6.nat_inside is not None and
+                    self.primary_ip6.nat_inside.assigned_object in vc_interfaces
+            ):
                 pass
             else:
                 raise ValidationError({
@@ -978,9 +987,10 @@ class Device(
 
         if hasattr(self, 'vc_master_for') and self.vc_master_for and self.vc_master_for != self.virtual_chassis:
             raise ValidationError({
-                'virtual_chassis': _('Device cannot be removed from virtual chassis {virtual_chassis} because it is currently designated as its master.').format(
-                    virtual_chassis=self.vc_master_for
-                )
+                'virtual_chassis': _(
+                    'Device cannot be removed from virtual chassis {virtual_chassis} because it is currently '
+                    'designated as its master.'
+                ).format(virtual_chassis=self.vc_master_for)
             })
 
     def _instantiate_components(self, queryset, bulk_create=True):

+ 3 - 1
netbox/dcim/models/racks.py

@@ -379,7 +379,9 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
                 min_height = top_device.position + top_device.device_type.u_height - self.starting_unit
                 if self.u_height < min_height:
                     raise ValidationError({
-                        'u_height': _("Rack must be at least {min_height}U tall to house currently installed devices.").format(min_height=min_height)
+                        'u_height': _(
+                            "Rack must be at least {min_height}U tall to house currently installed devices."
+                        ).format(min_height=min_height)
                     })
 
             # Validate that the Rack's starting unit is less than or equal to the position of the lowest mounted Device

+ 4 - 1
netbox/dcim/svg/racks.py

@@ -153,7 +153,10 @@ class RackElevationSVG:
         if self.rack.desc_units:
             y += int((position - self.rack.starting_unit) * self.unit_height)
         else:
-            y += int((self.rack.u_height - position + self.rack.starting_unit) * self.unit_height) - int(height * self.unit_height)
+            y += (
+                int((self.rack.u_height - position + self.rack.starting_unit) * self.unit_height) -
+                int(height * self.unit_height)
+            )
 
         return x, y
 

+ 8 - 6
netbox/dcim/tables/devices.py

@@ -391,7 +391,8 @@ class ConsolePortTable(ModularDeviceComponentTable, PathEndpointTable):
         model = models.ConsolePort
         fields = (
             'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
-            'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', 'last_updated',
+            'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created',
+            'last_updated',
         )
         default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description')
 
@@ -431,7 +432,8 @@ class ConsoleServerPortTable(ModularDeviceComponentTable, PathEndpointTable):
         model = models.ConsoleServerPort
         fields = (
             'pk', 'id', 'name', 'device', 'module_bay', 'module', 'label', 'type', 'speed', 'description',
-            'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created', 'last_updated',
+            'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'inventory_items', 'tags', 'created',
+            'last_updated',
         )
         default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description')
 
@@ -987,8 +989,8 @@ class InventoryItemTable(DeviceComponentTable):
     class Meta(NetBoxTable.Meta):
         model = models.InventoryItem
         fields = (
-            'pk', 'id', 'name', 'device', 'parent', 'component', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial',
-            'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated',
+            'pk', 'id', 'name', 'device', 'parent', 'component', 'label', 'status', 'role', 'manufacturer', 'part_id',
+            'serial', 'asset_tag', 'description', 'discovered', 'tags', 'created', 'last_updated',
         )
         default_columns = (
             'pk', 'name', 'device', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag',
@@ -1006,8 +1008,8 @@ class DeviceInventoryItemTable(InventoryItemTable):
     class Meta(NetBoxTable.Meta):
         model = models.InventoryItem
         fields = (
-            'pk', 'id', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component',
-            'description', 'discovered', 'tags', 'actions',
+            'pk', 'id', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag',
+            'component', 'description', 'discovered', 'tags', 'actions',
         )
         default_columns = (
             'pk', 'name', 'label', 'status', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'component',

+ 72 - 15
netbox/dcim/tests/test_api.py

@@ -205,13 +205,41 @@ class LocationTest(APIViewTestCases.APIViewTestCase):
         Site.objects.bulk_create(sites)
 
         parent_locations = (
-            Location.objects.create(site=sites[0], name='Parent Location 1', slug='parent-location-1', status=LocationStatusChoices.STATUS_ACTIVE),
-            Location.objects.create(site=sites[1], name='Parent Location 2', slug='parent-location-2', status=LocationStatusChoices.STATUS_ACTIVE),
+            Location.objects.create(
+                site=sites[0],
+                name='Parent Location 1',
+                slug='parent-location-1',
+                status=LocationStatusChoices.STATUS_ACTIVE,
+            ),
+            Location.objects.create(
+                site=sites[1],
+                name='Parent Location 2',
+                slug='parent-location-2',
+                status=LocationStatusChoices.STATUS_ACTIVE,
+            ),
         )
 
-        Location.objects.create(site=sites[0], name='Location 1', slug='location-1', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE)
-        Location.objects.create(site=sites[0], name='Location 2', slug='location-2', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE)
-        Location.objects.create(site=sites[0], name='Location 3', slug='location-3', parent=parent_locations[0], status=LocationStatusChoices.STATUS_ACTIVE)
+        Location.objects.create(
+            site=sites[0],
+            name='Location 1',
+            slug='location-1',
+            parent=parent_locations[0],
+            status=LocationStatusChoices.STATUS_ACTIVE,
+        )
+        Location.objects.create(
+            site=sites[0],
+            name='Location 2',
+            slug='location-2',
+            parent=parent_locations[0],
+            status=LocationStatusChoices.STATUS_ACTIVE,
+        )
+        Location.objects.create(
+            site=sites[0],
+            name='Location 3',
+            slug='location-3',
+            parent=parent_locations[0],
+            status=LocationStatusChoices.STATUS_ACTIVE,
+        )
 
         cls.create_data = [
             {
@@ -290,9 +318,24 @@ class RackTypeTest(APIViewTestCases.APIViewTestCase):
         Manufacturer.objects.bulk_create(manufacturers)
 
         rack_types = (
-            RackType(manufacturer=manufacturers[0], model='Rack Type 1', slug='rack-type-1', form_factor=RackFormFactorChoices.TYPE_CABINET,),
-            RackType(manufacturer=manufacturers[0], model='Rack Type 2', slug='rack-type-2', form_factor=RackFormFactorChoices.TYPE_CABINET,),
-            RackType(manufacturer=manufacturers[0], model='Rack Type 3', slug='rack-type-3', form_factor=RackFormFactorChoices.TYPE_CABINET,),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='Rack Type 1',
+                slug='rack-type-1',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='Rack Type 2',
+                slug='rack-type-2',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='Rack Type 3',
+                slug='rack-type-3',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
         )
         RackType.objects.bulk_create(rack_types)
 
@@ -1050,10 +1093,18 @@ class InventoryItemTemplateTest(APIViewTestCases.APIViewTestCase):
         role = InventoryItemRole.objects.create(name='Inventory Item Role 1', slug='inventory-item-role-1')
 
         inventory_item_templates = (
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturer, role=role),
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturer, role=role),
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturer, role=role),
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 4', manufacturer=manufacturer, role=role),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturer, role=role
+            ),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturer, role=role
+            ),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturer, role=role
+            ),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 4', manufacturer=manufacturer, role=role
+            ),
         )
         for item in inventory_item_templates:
             item.save()
@@ -1961,9 +2012,15 @@ class InventoryItemTest(APIViewTestCases.APIViewTestCase):
         )
         Interface.objects.bulk_create(interfaces)
 
-        InventoryItem.objects.create(device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer, component=interfaces[0])
-        InventoryItem.objects.create(device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer, component=interfaces[1])
-        InventoryItem.objects.create(device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer, component=interfaces[2])
+        InventoryItem.objects.create(
+            device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer, component=interfaces[0]
+        )
+        InventoryItem.objects.create(
+            device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer, component=interfaces[1]
+        )
+        InventoryItem.objects.create(
+            device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer, component=interfaces[2]
+        )
 
         cls.create_data = [
             {

+ 214 - 48
netbox/dcim/tests/test_cablepaths.py

@@ -661,24 +661,64 @@ class CablePathTestCase(TestCase):
         )
         cable5.save()
         path1 = self.assertPathExists(
-            ([interface1, interface2], cable1, frontport1_1, rearport1, cable3, rearport2, frontport2_1, cable4, [interface5, interface6]),
+            (
+                [interface1, interface2],
+                cable1,
+                frontport1_1,
+                rearport1,
+                cable3,
+                rearport2,
+                frontport2_1,
+                cable4,
+                [interface5, interface6],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path2 = self.assertPathExists(
-            ([interface3, interface4], cable2, frontport1_2, rearport1, cable3, rearport2, frontport2_2, cable5, [interface7, interface8]),
+            (
+                [interface3, interface4],
+                cable2,
+                frontport1_2,
+                rearport1,
+                cable3,
+                rearport2,
+                frontport2_2,
+                cable5,
+                [interface7, interface8],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path3 = self.assertPathExists(
-            ([interface5, interface6], cable4, frontport2_1, rearport2, cable3, rearport1, frontport1_1, cable1, [interface1, interface2]),
+            (
+                [interface5, interface6],
+                cable4,
+                frontport2_1,
+                rearport2,
+                cable3,
+                rearport1,
+                frontport1_1,
+                cable1,
+                [interface1, interface2],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path4 = self.assertPathExists(
-            ([interface7, interface8], cable5, frontport2_2, rearport2, cable3, rearport1, frontport1_2, cable2, [interface3, interface4]),
+            (
+                [interface7, interface8],
+                cable5,
+                frontport2_2,
+                rearport2,
+                cable3,
+                rearport1,
+                frontport1_2,
+                cable2,
+                [interface3, interface4],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         self.assertEqual(CablePath.objects.count(), 4)
 
@@ -1167,7 +1207,11 @@ class CablePathTestCase(TestCase):
         [IF1] --C1-- [CT1]
         """
         interface1 = Interface.objects.create(device=self.device, name='Interface 1')
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
 
         # Create cable 1
         cable1 = Cable(
@@ -1198,7 +1242,11 @@ class CablePathTestCase(TestCase):
         """
         interface1 = Interface.objects.create(device=self.device, name='Interface 1')
         interface2 = Interface.objects.create(device=self.device, name='Interface 2')
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
 
         # Create cable 1
         cable1 = Cable(
@@ -1214,7 +1262,11 @@ class CablePathTestCase(TestCase):
         )
 
         # Create CT2
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z')
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='Z'
+        )
 
         # Check for partial path to site
         self.assertPathExists(
@@ -1266,7 +1318,11 @@ class CablePathTestCase(TestCase):
         interface2 = Interface.objects.create(device=self.device, name='Interface 2')
         interface3 = Interface.objects.create(device=self.device, name='Interface 3')
         interface4 = Interface.objects.create(device=self.device, name='Interface 4')
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
 
         # Create cable 1
         cable1 = Cable(
@@ -1282,7 +1338,11 @@ class CablePathTestCase(TestCase):
         )
 
         # Create CT2
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z')
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='Z'
+        )
 
         # Check for partial path to site
         self.assertPathExists(
@@ -1299,14 +1359,28 @@ class CablePathTestCase(TestCase):
 
         # Check for complete path in each direction
         self.assertPathExists(
-            ([interface1, interface2], cable1, circuittermination1, circuittermination2, cable2, [interface3, interface4]),
+            (
+                [interface1, interface2],
+                cable1,
+                circuittermination1,
+                circuittermination2,
+                cable2,
+                [interface3, interface4],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         self.assertPathExists(
-            ([interface3, interface4], cable2, circuittermination2, circuittermination1, cable1, [interface1, interface2]),
+            (
+                [interface3, interface4],
+                cable2,
+                circuittermination2,
+                circuittermination1,
+                cable1,
+                [interface1, interface2],
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         self.assertEqual(CablePath.objects.count(), 2)
 
@@ -1335,8 +1409,16 @@ class CablePathTestCase(TestCase):
         """
         interface1 = Interface.objects.create(device=self.device, name='Interface 1')
         site2 = Site.objects.create(name='Site 2', slug='site-2')
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=site2, term_side='Z')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=site2,
+            term_side='Z'
+        )
 
         # Create cable 1
         cable1 = Cable(
@@ -1365,8 +1447,16 @@ class CablePathTestCase(TestCase):
         """
         interface1 = Interface.objects.create(device=self.device, name='Interface 1')
         providernetwork = ProviderNetwork.objects.create(name='Provider Network 1', provider=self.circuit.provider)
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=providernetwork, term_side='Z')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=providernetwork,
+            term_side='Z'
+        )
 
         # Create cable 1
         cable1 = Cable(
@@ -1413,8 +1503,15 @@ class CablePathTestCase(TestCase):
         frontport2_2 = FrontPort.objects.create(
             device=self.device, name='Front Port 2:2', rear_port=rearport2, rear_port_position=2
         )
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site, term_side='Z'
+        )
 
         # Create cables
         cable1 = Cable(
@@ -1499,10 +1596,26 @@ class CablePathTestCase(TestCase):
         interface1 = Interface.objects.create(device=self.device, name='Interface 1')
         interface2 = Interface.objects.create(device=self.device, name='Interface 2')
         circuit2 = Circuit.objects.create(provider=self.circuit.provider, type=self.circuit.type, cid='Circuit 2')
-        circuittermination1 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='A')
-        circuittermination2 = CircuitTermination.objects.create(circuit=self.circuit, termination=self.site, term_side='Z')
-        circuittermination3 = CircuitTermination.objects.create(circuit=circuit2, termination=self.site, term_side='A')
-        circuittermination4 = CircuitTermination.objects.create(circuit=circuit2, termination=self.site, term_side='Z')
+        circuittermination1 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='A'
+        )
+        circuittermination2 = CircuitTermination.objects.create(
+            circuit=self.circuit,
+            termination=self.site,
+            term_side='Z'
+        )
+        circuittermination3 = CircuitTermination.objects.create(
+            circuit=circuit2,
+            termination=self.site,
+            term_side='A'
+        )
+        circuittermination4 = CircuitTermination.objects.create(
+            circuit=circuit2,
+            termination=self.site,
+            term_side='Z'
+        )
 
         # Create cables
         cable1 = Cable(
@@ -1706,45 +1819,95 @@ class CablePathTestCase(TestCase):
         )
         cable3.save()
         self.assertPathExists(
-            (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2)),
-            is_complete=False
+            (
+                interface1,
+                cable1,
+                (frontport1_1, frontport1_2),
+                rearport1,
+                cable3,
+                rearport2,
+                (frontport2_1, frontport2_2),
+            ),
+            is_complete=False,
         )
         self.assertPathExists(
-            (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4)),
-            is_complete=False
+            (
+                interface2,
+                cable2,
+                (frontport1_3, frontport1_4),
+                rearport1,
+                cable3,
+                rearport2,
+                (frontport2_3, frontport2_4),
+            ),
+            is_complete=False,
         )
         self.assertEqual(CablePath.objects.count(), 2)
 
         # Create cables 4-5
-        cable4 = Cable(
-            a_terminations=[frontport2_1, frontport2_2],
-            b_terminations=[interface3]
-        )
+        cable4 = Cable(a_terminations=[frontport2_1, frontport2_2], b_terminations=[interface3])
         cable4.save()
-        cable5 = Cable(
-            a_terminations=[frontport2_3, frontport2_4],
-            b_terminations=[interface4]
-        )
+        cable5 = Cable(a_terminations=[frontport2_3, frontport2_4], b_terminations=[interface4])
         cable5.save()
         path1 = self.assertPathExists(
-            (interface1, cable1, (frontport1_1, frontport1_2), rearport1, cable3, rearport2, (frontport2_1, frontport2_2), cable4, interface3),
+            (
+                interface1,
+                cable1,
+                (frontport1_1, frontport1_2),
+                rearport1,
+                cable3,
+                rearport2,
+                (frontport2_1, frontport2_2),
+                cable4,
+                interface3,
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path2 = self.assertPathExists(
-            (interface2, cable2, (frontport1_3, frontport1_4), rearport1, cable3, rearport2, (frontport2_3, frontport2_4), cable5, interface4),
+            (
+                interface2,
+                cable2,
+                (frontport1_3, frontport1_4),
+                rearport1,
+                cable3,
+                rearport2,
+                (frontport2_3, frontport2_4),
+                cable5,
+                interface4,
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path3 = self.assertPathExists(
-            (interface3, cable4, (frontport2_1, frontport2_2), rearport2, cable3, rearport1, (frontport1_1, frontport1_2), cable1, interface1),
+            (
+                interface3,
+                cable4,
+                (frontport2_1, frontport2_2),
+                rearport2,
+                cable3,
+                rearport1,
+                (frontport1_1, frontport1_2),
+                cable1,
+                interface1,
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         path4 = self.assertPathExists(
-            (interface4, cable5, (frontport2_3, frontport2_4), rearport2, cable3, rearport1, (frontport1_3, frontport1_4), cable2, interface2),
+            (
+                interface4,
+                cable5,
+                (frontport2_3, frontport2_4),
+                rearport2,
+                cable3,
+                rearport1,
+                (frontport1_3, frontport1_4),
+                cable2,
+                interface2,
+            ),
             is_complete=True,
-            is_active=True
+            is_active=True,
         )
         self.assertEqual(CablePath.objects.count(), 4)
 
@@ -1809,7 +1972,10 @@ class CablePathTestCase(TestCase):
         )
         cable1.save()
         self.assertPathExists(
-            (interface1, cable1, (frontport1, frontport3), (rearport1, rearport3), (cable2, cable4), (rearport2, rearport4), (frontport2, frontport4)),
+            (
+                interface1, cable1, (frontport1, frontport3), (rearport1, rearport3), (cable2, cable4),
+                (rearport2, rearport4), (frontport2, frontport4)
+            ),
             is_complete=False
         )
         self.assertEqual(CablePath.objects.count(), 1)

+ 705 - 103
netbox/dcim/tests/test_filtersets.py

@@ -243,9 +243,41 @@ class SiteTestCase(TestCase, ChangeLoggedFilterSetTests):
         ASN.objects.bulk_create(asns)
 
         sites = (
-            Site(name='Site 1', slug='site-1', region=regions[0], group=groups[0], tenant=tenants[0], status=SiteStatusChoices.STATUS_ACTIVE, facility='Facility 1', latitude=10, longitude=10, description='foobar1'),
-            Site(name='Site 2', slug='site-2', region=regions[1], group=groups[1], tenant=tenants[1], status=SiteStatusChoices.STATUS_PLANNED, facility='Facility 2', latitude=20, longitude=20, description='foobar2'),
-            Site(name='Site 3', slug='site-3', region=regions[2], group=groups[2], tenant=tenants[2], status=SiteStatusChoices.STATUS_RETIRED, facility='Facility 3', latitude=30, longitude=30),
+            Site(
+                name='Site 1',
+                slug='site-1',
+                region=regions[0],
+                group=groups[0],
+                tenant=tenants[0],
+                status=SiteStatusChoices.STATUS_ACTIVE,
+                facility='Facility 1',
+                latitude=10,
+                longitude=10,
+                description='foobar1',
+            ),
+            Site(
+                name='Site 2',
+                slug='site-2',
+                region=regions[1],
+                group=groups[1],
+                tenant=tenants[1],
+                status=SiteStatusChoices.STATUS_PLANNED,
+                facility='Facility 2',
+                latitude=20,
+                longitude=20,
+                description='foobar2',
+            ),
+            Site(
+                name='Site 3',
+                slug='site-3',
+                region=regions[2],
+                group=groups[2],
+                tenant=tenants[2],
+                status=SiteStatusChoices.STATUS_RETIRED,
+                facility='Facility 3',
+                latitude=30,
+                longitude=30,
+            ),
         )
         Site.objects.bulk_create(sites)
         sites[0].asns.set([asns[0]])
@@ -361,9 +393,33 @@ class LocationTestCase(TestCase, ChangeLoggedFilterSetTests):
             location.save()
 
         locations = (
-            Location(name='Location 1A', slug='location-1a', site=sites[0], parent=parent_locations[0], status=LocationStatusChoices.STATUS_PLANNED, facility='Facility 1', description='foobar1'),
-            Location(name='Location 2A', slug='location-2a', site=sites[1], parent=parent_locations[1], status=LocationStatusChoices.STATUS_STAGING, facility='Facility 2', description='foobar2'),
-            Location(name='Location 3A', slug='location-3a', site=sites[2], parent=parent_locations[2], status=LocationStatusChoices.STATUS_DECOMMISSIONING, facility='Facility 3', description='foobar3'),
+            Location(
+                name='Location 1A',
+                slug='location-1a',
+                site=sites[0],
+                parent=parent_locations[0],
+                status=LocationStatusChoices.STATUS_PLANNED,
+                facility='Facility 1',
+                description='foobar1',
+            ),
+            Location(
+                name='Location 2A',
+                slug='location-2a',
+                site=sites[1],
+                parent=parent_locations[1],
+                status=LocationStatusChoices.STATUS_STAGING,
+                facility='Facility 2',
+                description='foobar2',
+            ),
+            Location(
+                name='Location 3A',
+                slug='location-3a',
+                site=sites[2],
+                parent=parent_locations[2],
+                status=LocationStatusChoices.STATUS_DECOMMISSIONING,
+                facility='Facility 3',
+                description='foobar3',
+            ),
         )
         for location in locations:
             location.save()
@@ -1222,10 +1278,22 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
             RearPortTemplate(device_type=device_types[1], name='Rear Port 2', type=PortTypeChoices.TYPE_8P8C),
         )
         RearPortTemplate.objects.bulk_create(rear_ports)
-        FrontPortTemplate.objects.bulk_create((
-            FrontPortTemplate(device_type=device_types[0], name='Front Port 1', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[0]),
-            FrontPortTemplate(device_type=device_types[1], name='Front Port 2', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[1]),
-        ))
+        FrontPortTemplate.objects.bulk_create(
+            (
+                FrontPortTemplate(
+                    device_type=device_types[0],
+                    name='Front Port 1',
+                    type=PortTypeChoices.TYPE_8P8C,
+                    rear_port=rear_ports[0],
+                ),
+                FrontPortTemplate(
+                    device_type=device_types[1],
+                    name='Front Port 2',
+                    type=PortTypeChoices.TYPE_8P8C,
+                    rear_port=rear_ports[1],
+                ),
+            )
+        )
         ModuleBayTemplate.objects.bulk_create((
             ModuleBayTemplate(device_type=device_types[0], name='Module Bay 1'),
             ModuleBayTemplate(device_type=device_types[1], name='Module Bay 2'),
@@ -1435,10 +1503,22 @@ class ModuleTypeTestCase(TestCase, ChangeLoggedFilterSetTests):
             RearPortTemplate(module_type=module_types[1], name='Rear Port 2', type=PortTypeChoices.TYPE_8P8C),
         )
         RearPortTemplate.objects.bulk_create(rear_ports)
-        FrontPortTemplate.objects.bulk_create((
-            FrontPortTemplate(module_type=module_types[0], name='Front Port 1', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[0]),
-            FrontPortTemplate(module_type=module_types[1], name='Front Port 2', type=PortTypeChoices.TYPE_8P8C, rear_port=rear_ports[1]),
-        ))
+        FrontPortTemplate.objects.bulk_create(
+            (
+                FrontPortTemplate(
+                    module_type=module_types[0],
+                    name='Front Port 1',
+                    type=PortTypeChoices.TYPE_8P8C,
+                    rear_port=rear_ports[0],
+                ),
+                FrontPortTemplate(
+                    module_type=module_types[1],
+                    name='Front Port 2',
+                    type=PortTypeChoices.TYPE_8P8C,
+                    rear_port=rear_ports[1],
+                ),
+            )
+        )
 
     def test_q(self):
         params = {'q': 'foobar1'}
@@ -1893,11 +1973,19 @@ class ModuleBayTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTests,
         )
         ModuleType.objects.bulk_create(module_types)
 
-        ModuleBayTemplate.objects.bulk_create((
-            ModuleBayTemplate(device_type=device_types[0], name='Module Bay 1', description='foobar1'),
-            ModuleBayTemplate(device_type=device_types[1], name='Module Bay 2', description='foobar2', module_type=module_types[0]),
-            ModuleBayTemplate(device_type=device_types[2], name='Module Bay 3', description='foobar3', module_type=module_types[1]),
-        ))
+        ModuleBayTemplate.objects.bulk_create(
+            (
+                ModuleBayTemplate(
+                    device_type=device_types[0], name='Module Bay 1', description='foobar1'
+                ),
+                ModuleBayTemplate(
+                    device_type=device_types[1], name='Module Bay 2', description='foobar2', module_type=module_types[0]
+                ),
+                ModuleBayTemplate(
+                    device_type=device_types[2], name='Module Bay 3', description='foobar3', module_type=module_types[1]
+                ),
+            )
+        )
 
     def test_name(self):
         params = {'name': ['Module Bay 1', 'Module Bay 2']}
@@ -1996,9 +2084,15 @@ class InventoryItemTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTe
             item.save()
 
         child_inventory_item_templates = (
-            InventoryItemTemplate(device_type=device_types[0], name='Inventory Item 1A', parent=inventory_item_templates[0]),
-            InventoryItemTemplate(device_type=device_types[1], name='Inventory Item 2A', parent=inventory_item_templates[1]),
-            InventoryItemTemplate(device_type=device_types[2], name='Inventory Item 3A', parent=inventory_item_templates[2]),
+            InventoryItemTemplate(
+                device_type=device_types[0], name='Inventory Item 1A', parent=inventory_item_templates[0]
+            ),
+            InventoryItemTemplate(
+                device_type=device_types[1], name='Inventory Item 2A', parent=inventory_item_templates[1]
+            ),
+            InventoryItemTemplate(
+                device_type=device_types[2], name='Inventory Item 3A', parent=inventory_item_templates[2]
+            ),
         )
         for item in child_inventory_item_templates:
             item.save()
@@ -2848,10 +2942,41 @@ class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[0], role=roles[0], site=sites[3], status='offline'),  # For cable connections
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[3],
+                status='offline'
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -3029,10 +3154,41 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'),  # For cable connections
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[3],
+                status='offline'
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -3058,9 +3214,15 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL
         ConsolePort.objects.bulk_create(console_ports)
 
         console_server_ports = (
-            ConsoleServerPort(device=devices[0], module=modules[0], name='Console Server Port 1', label='A', description='First'),
-            ConsoleServerPort(device=devices[1], module=modules[1], name='Console Server Port 2', label='B', description='Second'),
-            ConsoleServerPort(device=devices[2], module=modules[2], name='Console Server Port 3', label='C', description='Third'),
+            ConsoleServerPort(
+                device=devices[0], module=modules[0], name='Console Server Port 1', label='A', description='First'
+            ),
+            ConsoleServerPort(
+                device=devices[1], module=modules[1], name='Console Server Port 2', label='B', description='Second'
+            ),
+            ConsoleServerPort(
+                device=devices[2], module=modules[2], name='Console Server Port 3', label='C', description='Third'
+            ),
         )
         ConsoleServerPort.objects.bulk_create(console_server_ports)
 
@@ -3210,10 +3372,41 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'),  # For cable connections
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[3],
+                status='offline'
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -3239,9 +3432,33 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         PowerOutlet.objects.bulk_create(power_outlets)
 
         power_ports = (
-            PowerPort(device=devices[0], module=modules[0], name='Power Port 1', label='A', maximum_draw=100, allocated_draw=50, description='First'),
-            PowerPort(device=devices[1], module=modules[1], name='Power Port 2', label='B', maximum_draw=200, allocated_draw=100, description='Second'),
-            PowerPort(device=devices[2], module=modules[2], name='Power Port 3', label='C', maximum_draw=300, allocated_draw=150, description='Third'),
+            PowerPort(
+                device=devices[0],
+                module=modules[0],
+                name='Power Port 1',
+                label='A',
+                maximum_draw=100,
+                allocated_draw=50,
+                description='First',
+            ),
+            PowerPort(
+                device=devices[1],
+                module=modules[1],
+                name='Power Port 2',
+                label='B',
+                maximum_draw=200,
+                allocated_draw=100,
+                description='Second',
+            ),
+            PowerPort(
+                device=devices[2],
+                module=modules[2],
+                name='Power Port 3',
+                label='C',
+                maximum_draw=300,
+                allocated_draw=150,
+                description='Third',
+            ),
         )
         PowerPort.objects.bulk_create(power_ports)
 
@@ -3399,10 +3616,41 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'),  # For cable connections
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[3],
+                status='offline'
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -3428,9 +3676,33 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
         PowerPort.objects.bulk_create(power_ports)
 
         power_outlets = (
-            PowerOutlet(device=devices[0], module=modules[0], name='Power Outlet 1', label='A', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_A, description='First', color='ff0000'),
-            PowerOutlet(device=devices[1], module=modules[1], name='Power Outlet 2', label='B', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_B, description='Second', color='00ff00'),
-            PowerOutlet(device=devices[2], module=modules[2], name='Power Outlet 3', label='C', feed_leg=PowerOutletFeedLegChoices.FEED_LEG_C, description='Third', color='0000ff'),
+            PowerOutlet(
+                device=devices[0],
+                module=modules[0],
+                name='Power Outlet 1',
+                label='A',
+                feed_leg=PowerOutletFeedLegChoices.FEED_LEG_A,
+                description='First',
+                color='ff0000',
+            ),
+            PowerOutlet(
+                device=devices[1],
+                module=modules[1],
+                name='Power Outlet 2',
+                label='B',
+                feed_leg=PowerOutletFeedLegChoices.FEED_LEG_B,
+                description='Second',
+                color='00ff00',
+            ),
+            PowerOutlet(
+                device=devices[2],
+                module=modules[2],
+                name='Power Outlet 3',
+                label='C',
+                feed_leg=PowerOutletFeedLegChoices.FEED_LEG_C,
+                description='Third',
+                color='0000ff',
+            ),
         )
         PowerOutlet.objects.bulk_create(power_outlets)
 
@@ -3672,8 +3944,12 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
 
         # Virtual Device Context Creation
         vdcs = (
-            VirtualDeviceContext(device=devices[4], name='VDC 1', identifier=1, status=VirtualDeviceContextStatusChoices.STATUS_ACTIVE),
-            VirtualDeviceContext(device=devices[4], name='VDC 2', identifier=2, status=VirtualDeviceContextStatusChoices.STATUS_PLANNED),
+            VirtualDeviceContext(
+                device=devices[4], name='VDC 1', identifier=1, status=VirtualDeviceContextStatusChoices.STATUS_ACTIVE
+            ),
+            VirtualDeviceContext(
+                device=devices[4], name='VDC 2', identifier=2, status=VirtualDeviceContextStatusChoices.STATUS_PLANNED
+            ),
         )
         VirtualDeviceContext.objects.bulk_create(vdcs)
 
@@ -3886,9 +4162,24 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         # Create child interfaces
         parent_interface = Interface.objects.first()
         child_interfaces = (
-            Interface(device=parent_interface.device, name='Child 1', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL),
-            Interface(device=parent_interface.device, name='Child 2', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL),
-            Interface(device=parent_interface.device, name='Child 3', parent=parent_interface, type=InterfaceTypeChoices.TYPE_VIRTUAL),
+            Interface(
+                device=parent_interface.device,
+                name='Child 1',
+                parent=parent_interface,
+                type=InterfaceTypeChoices.TYPE_VIRTUAL,
+            ),
+            Interface(
+                device=parent_interface.device,
+                name='Child 2',
+                parent=parent_interface,
+                type=InterfaceTypeChoices.TYPE_VIRTUAL,
+            ),
+            Interface(
+                device=parent_interface.device,
+                name='Child 3',
+                parent=parent_interface,
+                type=InterfaceTypeChoices.TYPE_VIRTUAL,
+            ),
         )
         Interface.objects.bulk_create(child_interfaces)
 
@@ -3899,9 +4190,24 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         # Create bridged interfaces
         bridge_interface = Interface.objects.first()
         bridged_interfaces = (
-            Interface(device=bridge_interface.device, name='Bridged 1', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED),
-            Interface(device=bridge_interface.device, name='Bridged 2', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED),
-            Interface(device=bridge_interface.device, name='Bridged 3', bridge=bridge_interface, type=InterfaceTypeChoices.TYPE_1GE_FIXED),
+            Interface(
+                device=bridge_interface.device,
+                name='Bridged 1',
+                bridge=bridge_interface,
+                type=InterfaceTypeChoices.TYPE_1GE_FIXED,
+            ),
+            Interface(
+                device=bridge_interface.device,
+                name='Bridged 2',
+                bridge=bridge_interface,
+                type=InterfaceTypeChoices.TYPE_1GE_FIXED,
+            ),
+            Interface(
+                device=bridge_interface.device,
+                name='Bridged 3',
+                bridge=bridge_interface,
+                type=InterfaceTypeChoices.TYPE_1GE_FIXED,
+            ),
         )
         Interface.objects.bulk_create(bridged_interfaces)
 
@@ -4134,23 +4440,54 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'),  # For cable connections
-        )
-        Device.objects.bulk_create(devices)
-
-        module_bays = (
-            ModuleBay(device=devices[0], name='Module Bay 1'),
-            ModuleBay(device=devices[1], name='Module Bay 2'),
-            ModuleBay(device=devices[2], name='Module Bay 3'),
-        )
-        for module_bay in module_bays:
-            module_bay.save()
-
-        modules = (
-            Module(device=devices[0], module_bay=module_bays[0], module_type=module_type),
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[3],
+                status='offline'
+            ),
+        )
+        Device.objects.bulk_create(devices)
+
+        module_bays = (
+            ModuleBay(device=devices[0], name='Module Bay 1'),
+            ModuleBay(device=devices[1], name='Module Bay 2'),
+            ModuleBay(device=devices[2], name='Module Bay 3'),
+        )
+        for module_bay in module_bays:
+            module_bay.save()
+
+        modules = (
+            Module(device=devices[0], module_bay=module_bays[0], module_type=module_type),
             Module(device=devices[1], module_bay=module_bays[1], module_type=module_type),
             Module(device=devices[2], module_bay=module_bays[2], module_type=module_type),
         )
@@ -4167,12 +4504,63 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         RearPort.objects.bulk_create(rear_ports)
 
         front_ports = (
-            FrontPort(device=devices[0], module=modules[0], name='Front Port 1', label='A', type=PortTypeChoices.TYPE_8P8C, color=ColorChoices.COLOR_RED, rear_port=rear_ports[0], rear_port_position=1, description='First'),
-            FrontPort(device=devices[1], module=modules[1], name='Front Port 2', label='B', type=PortTypeChoices.TYPE_110_PUNCH, color=ColorChoices.COLOR_GREEN, rear_port=rear_ports[1], rear_port_position=2, description='Second'),
-            FrontPort(device=devices[2], module=modules[2], name='Front Port 3', label='C', type=PortTypeChoices.TYPE_BNC, color=ColorChoices.COLOR_BLUE, rear_port=rear_ports[2], rear_port_position=3, description='Third'),
-            FrontPort(device=devices[3], name='Front Port 4', label='D', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[3], rear_port_position=1),
-            FrontPort(device=devices[3], name='Front Port 5', label='E', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[4], rear_port_position=1),
-            FrontPort(device=devices[3], name='Front Port 6', label='F', type=PortTypeChoices.TYPE_FC, rear_port=rear_ports[5], rear_port_position=1),
+            FrontPort(
+                device=devices[0],
+                module=modules[0],
+                name='Front Port 1',
+                label='A',
+                type=PortTypeChoices.TYPE_8P8C,
+                color=ColorChoices.COLOR_RED,
+                rear_port=rear_ports[0],
+                rear_port_position=1,
+                description='First',
+            ),
+            FrontPort(
+                device=devices[1],
+                module=modules[1],
+                name='Front Port 2',
+                label='B',
+                type=PortTypeChoices.TYPE_110_PUNCH,
+                color=ColorChoices.COLOR_GREEN,
+                rear_port=rear_ports[1],
+                rear_port_position=2,
+                description='Second',
+            ),
+            FrontPort(
+                device=devices[2],
+                module=modules[2],
+                name='Front Port 3',
+                label='C',
+                type=PortTypeChoices.TYPE_BNC,
+                color=ColorChoices.COLOR_BLUE,
+                rear_port=rear_ports[2],
+                rear_port_position=3,
+                description='Third',
+            ),
+            FrontPort(
+                device=devices[3],
+                name='Front Port 4',
+                label='D',
+                type=PortTypeChoices.TYPE_FC,
+                rear_port=rear_ports[3],
+                rear_port_position=1,
+            ),
+            FrontPort(
+                device=devices[3],
+                name='Front Port 5',
+                label='E',
+                type=PortTypeChoices.TYPE_FC,
+                rear_port=rear_ports[4],
+                rear_port_position=1,
+            ),
+            FrontPort(
+                device=devices[3],
+                name='Front Port 6',
+                label='F',
+                type=PortTypeChoices.TYPE_FC,
+                rear_port=rear_ports[5],
+                rear_port_position=1,
+            ),
         )
         FrontPort.objects.bulk_create(front_ports)
 
@@ -4324,10 +4712,41 @@ class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilt
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
-            Device(name=None, device_type=device_types[2], role=roles[2], site=sites[3], status='offline'),  # For cable connections
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
+            # For cable connections
+            Device(
+                name=None,
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[3],
+                status='offline'
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -4347,9 +4766,36 @@ class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilt
         Module.objects.bulk_create(modules)
 
         rear_ports = (
-            RearPort(device=devices[0], module=modules[0], name='Rear Port 1', label='A', type=PortTypeChoices.TYPE_8P8C, color=ColorChoices.COLOR_RED, positions=1, description='First'),
-            RearPort(device=devices[1], module=modules[1], name='Rear Port 2', label='B', type=PortTypeChoices.TYPE_110_PUNCH, color=ColorChoices.COLOR_GREEN, positions=2, description='Second'),
-            RearPort(device=devices[2], module=modules[2], name='Rear Port 3', label='C', type=PortTypeChoices.TYPE_BNC, color=ColorChoices.COLOR_BLUE, positions=3, description='Third'),
+            RearPort(
+                device=devices[0],
+                module=modules[0],
+                name='Rear Port 1',
+                label='A',
+                type=PortTypeChoices.TYPE_8P8C,
+                color=ColorChoices.COLOR_RED,
+                positions=1,
+                description='First',
+            ),
+            RearPort(
+                device=devices[1],
+                module=modules[1],
+                name='Rear Port 2',
+                label='B',
+                type=PortTypeChoices.TYPE_110_PUNCH,
+                color=ColorChoices.COLOR_GREEN,
+                positions=2,
+                description='Second',
+            ),
+            RearPort(
+                device=devices[2],
+                module=modules[2],
+                name='Rear Port 3',
+                label='C',
+                type=PortTypeChoices.TYPE_BNC,
+                color=ColorChoices.COLOR_BLUE,
+                positions=3,
+                description='Third',
+            ),
             RearPort(device=devices[3], name='Rear Port 4', label='D', type=PortTypeChoices.TYPE_FC, positions=4),
             RearPort(device=devices[3], name='Rear Port 5', label='E', type=PortTypeChoices.TYPE_FC, positions=5),
             RearPort(device=devices[3], name='Rear Port 6', label='F', type=PortTypeChoices.TYPE_FC, positions=6),
@@ -4506,9 +4952,33 @@ class ModuleBayTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -4654,9 +5124,33 @@ class DeviceBayTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0], status='active'),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1], status='planned'),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2], status='offline'),
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+                status='active',
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+                status='planned',
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+                status='offline',
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -4788,9 +5282,30 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
         Rack.objects.bulk_create(racks)
 
         devices = (
-            Device(name='Device 1', device_type=device_types[0], role=roles[0], site=sites[0], location=locations[0], rack=racks[0]),
-            Device(name='Device 2', device_type=device_types[1], role=roles[1], site=sites[1], location=locations[1], rack=racks[1]),
-            Device(name='Device 3', device_type=device_types[2], role=roles[2], site=sites[2], location=locations[2], rack=racks[2]),
+            Device(
+                name='Device 1',
+                device_type=device_types[0],
+                role=roles[0],
+                site=sites[0],
+                location=locations[0],
+                rack=racks[0],
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_types[1],
+                role=roles[1],
+                site=sites[1],
+                location=locations[1],
+                rack=racks[1],
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_types[2],
+                role=roles[2],
+                site=sites[2],
+                location=locations[2],
+                rack=racks[2],
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -4808,9 +5323,48 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
         )
 
         inventory_items = (
-            InventoryItem(device=devices[0], role=roles[0], manufacturer=manufacturers[0], name='Inventory Item 1', label='A', part_id='1001', serial='ABC', asset_tag='1001', discovered=True, status=ModuleStatusChoices.STATUS_ACTIVE, description='First', component=components[0]),
-            InventoryItem(device=devices[1], role=roles[1], manufacturer=manufacturers[1], name='Inventory Item 2', label='B', part_id='1002', serial='DEF', asset_tag='1002', discovered=True, status=ModuleStatusChoices.STATUS_PLANNED, description='Second', component=components[1]),
-            InventoryItem(device=devices[2], role=roles[2], manufacturer=manufacturers[2], name='Inventory Item 3', label='C', part_id='1003', serial='GHI', asset_tag='1003', discovered=False, status=ModuleStatusChoices.STATUS_FAILED, description='Third', component=components[2]),
+            InventoryItem(
+                device=devices[0],
+                role=roles[0],
+                manufacturer=manufacturers[0],
+                name='Inventory Item 1',
+                label='A',
+                part_id='1001',
+                serial='ABC',
+                asset_tag='1001',
+                discovered=True,
+                status=ModuleStatusChoices.STATUS_ACTIVE,
+                description='First',
+                component=components[0],
+            ),
+            InventoryItem(
+                device=devices[1],
+                role=roles[1],
+                manufacturer=manufacturers[1],
+                name='Inventory Item 2',
+                label='B',
+                part_id='1002',
+                serial='DEF',
+                asset_tag='1002',
+                discovered=True,
+                status=ModuleStatusChoices.STATUS_PLANNED,
+                description='Second',
+                component=components[1],
+            ),
+            InventoryItem(
+                device=devices[2],
+                role=roles[2],
+                manufacturer=manufacturers[2],
+                name='Inventory Item 3',
+                label='C',
+                part_id='1003',
+                serial='GHI',
+                asset_tag='1003',
+                discovered=False,
+                status=ModuleStatusChoices.STATUS_FAILED,
+                description='Third',
+                component=components[2],
+            ),
         )
         for i in inventory_items:
             i.save()
@@ -5127,12 +5681,60 @@ class CableTestCase(TestCase, ChangeLoggedFilterSetTests):
         role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
 
         devices = (
-            Device(name='Device 1', device_type=device_type, role=role, site=sites[0], rack=racks[0], location=locations[0], position=1),
-            Device(name='Device 2', device_type=device_type, role=role, site=sites[0], rack=racks[0], location=locations[0], position=2),
-            Device(name='Device 3', device_type=device_type, role=role, site=sites[1], rack=racks[1], location=locations[1], position=1),
-            Device(name='Device 4', device_type=device_type, role=role, site=sites[1], rack=racks[1], location=locations[1], position=2),
-            Device(name='Device 5', device_type=device_type, role=role, site=sites[2], rack=racks[2], location=locations[2], position=1),
-            Device(name='Device 6', device_type=device_type, role=role, site=sites[2], rack=racks[2], location=locations[2], position=2),
+            Device(
+                name='Device 1',
+                device_type=device_type,
+                role=role,
+                site=sites[0],
+                rack=racks[0],
+                location=locations[0],
+                position=1,
+            ),
+            Device(
+                name='Device 2',
+                device_type=device_type,
+                role=role,
+                site=sites[0],
+                rack=racks[0],
+                location=locations[0],
+                position=2,
+            ),
+            Device(
+                name='Device 3',
+                device_type=device_type,
+                role=role,
+                site=sites[1],
+                rack=racks[1],
+                location=locations[1],
+                position=1,
+            ),
+            Device(
+                name='Device 4',
+                device_type=device_type,
+                role=role,
+                site=sites[1],
+                rack=racks[1],
+                location=locations[1],
+                position=2,
+            ),
+            Device(
+                name='Device 5',
+                device_type=device_type,
+                role=role,
+                site=sites[2],
+                rack=racks[2],
+                location=locations[2],
+                position=1,
+            ),
+            Device(
+                name='Device 6',
+                device_type=device_type,
+                role=role,
+                site=sites[2],
+                rack=racks[2],
+                location=locations[2],
+                position=2,
+            ),
         )
         Device.objects.bulk_create(devices)
 

+ 23 - 4
netbox/dcim/tests/test_models.py

@@ -612,14 +612,31 @@ class DeviceTestCase(TestCase):
         device_role = DeviceRole.objects.first()
 
         # Device with site only should pass
-        Device(name='device1', site=sites[0], device_type=device_type, role=device_role).full_clean()
+        Device(
+            name='device1',
+            site=sites[0],
+            device_type=device_type,
+            role=device_role
+        ).full_clean()
 
         # Device with site, cluster non-site should pass
-        Device(name='device1', site=sites[0], device_type=device_type, role=device_role, cluster=clusters[2]).full_clean()
+        Device(
+            name='device1',
+            site=sites[0],
+            device_type=device_type,
+            role=device_role,
+            cluster=clusters[2]
+        ).full_clean()
 
         # Device with mismatched site & cluster should fail
         with self.assertRaises(ValidationError):
-            Device(name='device1', site=sites[0], device_type=device_type, role=device_role, cluster=clusters[1]).full_clean()
+            Device(
+                name='device1',
+                site=sites[0],
+                device_type=device_type,
+                role=device_role,
+                cluster=clusters[1]
+            ).full_clean()
 
 
 class ModuleBayTestCase(TestCase):
@@ -636,7 +653,9 @@ class ModuleBayTestCase(TestCase):
         # Create a CustomField with a default value & assign it to all component models
         location = Location.objects.create(name='Location 1', slug='location-1', site=site)
         rack = Rack.objects.create(name='Rack 1', site=site)
-        device = Device.objects.create(name='Device 1', device_type=device_type, role=device_role, site=site, location=location, rack=rack)
+        device = Device.objects.create(
+            name='Device 1', device_type=device_type, role=device_role, site=site, location=location, rack=rack
+        )
 
         module_bays = (
             ModuleBay(device=device, name='Module Bay 1', label='A', description='First'),

+ 137 - 32
netbox/dcim/tests/test_views.py

@@ -196,9 +196,27 @@ class LocationTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
         tenant = Tenant.objects.create(name='Tenant 1', slug='tenant-1')
 
         locations = (
-            Location(name='Location 1', slug='location-1', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant),
-            Location(name='Location 2', slug='location-2', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant),
-            Location(name='Location 3', slug='location-3', site=site, status=LocationStatusChoices.STATUS_ACTIVE, tenant=tenant),
+            Location(
+                name='Location 1',
+                slug='location-1',
+                site=site,
+                status=LocationStatusChoices.STATUS_ACTIVE,
+                tenant=tenant,
+            ),
+            Location(
+                name='Location 2',
+                slug='location-2',
+                site=site,
+                status=LocationStatusChoices.STATUS_ACTIVE,
+                tenant=tenant,
+            ),
+            Location(
+                name='Location 3',
+                slug='location-3',
+                site=site,
+                status=LocationStatusChoices.STATUS_ACTIVE,
+                tenant=tenant,
+            ),
         )
         for location in locations:
             location.save()
@@ -346,9 +364,24 @@ class RackTypeTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         Manufacturer.objects.bulk_create(manufacturers)
 
         rack_types = (
-            RackType(manufacturer=manufacturers[0], model='RackType 1', slug='rack-type-1', form_factor=RackFormFactorChoices.TYPE_CABINET,),
-            RackType(manufacturer=manufacturers[0], model='RackType 2', slug='rack-type-2', form_factor=RackFormFactorChoices.TYPE_CABINET,),
-            RackType(manufacturer=manufacturers[0], model='RackType 3', slug='rack-type-3', form_factor=RackFormFactorChoices.TYPE_CABINET,),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='RackType 1',
+                slug='rack-type-1',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='RackType 2',
+                slug='rack-type-2',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
+            RackType(
+                manufacturer=manufacturers[0],
+                model='RackType 3',
+                slug='rack-type-3',
+                form_factor=RackFormFactorChoices.TYPE_CABINET,
+            ),
         )
         RackType.objects.bulk_create(rack_types)
 
@@ -692,9 +725,15 @@ class DeviceTypeTestCase(
         )
         RearPortTemplate.objects.bulk_create(rear_ports)
         front_ports = (
-            FrontPortTemplate(device_type=devicetype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1),
-            FrontPortTemplate(device_type=devicetype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1),
-            FrontPortTemplate(device_type=devicetype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1),
+            FrontPortTemplate(
+                device_type=devicetype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1
+            ),
+            FrontPortTemplate(
+                device_type=devicetype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1
+            ),
+            FrontPortTemplate(
+                device_type=devicetype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1
+            ),
         )
         FrontPortTemplate.objects.bulk_create(front_ports)
 
@@ -1081,9 +1120,15 @@ class ModuleTypeTestCase(
         )
         RearPortTemplate.objects.bulk_create(rear_ports)
         front_ports = (
-            FrontPortTemplate(module_type=moduletype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1),
-            FrontPortTemplate(module_type=moduletype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1),
-            FrontPortTemplate(module_type=moduletype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1),
+            FrontPortTemplate(
+                module_type=moduletype, name='Front Port 1', rear_port=rear_ports[0], rear_port_position=1
+            ),
+            FrontPortTemplate(
+                module_type=moduletype, name='Front Port 2', rear_port=rear_ports[1], rear_port_position=1
+            ),
+            FrontPortTemplate(
+                module_type=moduletype, name='Front Port 3', rear_port=rear_ports[2], rear_port_position=1
+            ),
         )
         FrontPortTemplate.objects.bulk_create(front_ports)
 
@@ -1453,11 +1498,19 @@ class FrontPortTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
         )
         RearPortTemplate.objects.bulk_create(rearports)
 
-        FrontPortTemplate.objects.bulk_create((
-            FrontPortTemplate(device_type=devicetype, name='Front Port Template 1', rear_port=rearports[0], rear_port_position=1),
-            FrontPortTemplate(device_type=devicetype, name='Front Port Template 2', rear_port=rearports[1], rear_port_position=1),
-            FrontPortTemplate(device_type=devicetype, name='Front Port Template 3', rear_port=rearports[2], rear_port_position=1),
-        ))
+        FrontPortTemplate.objects.bulk_create(
+            (
+                FrontPortTemplate(
+                    device_type=devicetype, name='Front Port Template 1', rear_port=rearports[0], rear_port_position=1
+                ),
+                FrontPortTemplate(
+                    device_type=devicetype, name='Front Port Template 2', rear_port=rearports[1], rear_port_position=1
+                ),
+                FrontPortTemplate(
+                    device_type=devicetype, name='Front Port Template 3', rear_port=rearports[2], rear_port_position=1
+                ),
+            )
+        )
 
         cls.form_data = {
             'device_type': devicetype.pk,
@@ -1550,7 +1603,12 @@ class DeviceBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
     @classmethod
     def setUpTestData(cls):
         manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
-        devicetype = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1', subdevice_role=SubdeviceRoleChoices.ROLE_PARENT)
+        devicetype = DeviceType.objects.create(
+            manufacturer=manufacturer,
+            model='Device Type 1',
+            slug='device-type-1',
+            subdevice_role=SubdeviceRoleChoices.ROLE_PARENT
+        )
 
         DeviceBayTemplate.objects.bulk_create((
             DeviceBayTemplate(device_type=devicetype, name='Device Bay Template 1'),
@@ -1584,12 +1642,20 @@ class InventoryItemTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTes
             Manufacturer(name='Manufacturer 2', slug='manufacturer-2'),
         )
         Manufacturer.objects.bulk_create(manufacturers)
-        devicetype = DeviceType.objects.create(manufacturer=manufacturers[0], model='Device Type 1', slug='device-type-1')
+        devicetype = DeviceType.objects.create(
+            manufacturer=manufacturers[0], model='Device Type 1', slug='device-type-1'
+        )
 
         inventory_item_templates = (
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturers[0]),
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturers[0]),
-            InventoryItemTemplate(device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturers[0]),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 1', manufacturer=manufacturers[0]
+            ),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 2', manufacturer=manufacturers[0]
+            ),
+            InventoryItemTemplate(
+                device_type=devicetype, name='Inventory Item Template 3', manufacturer=manufacturers[0]
+            ),
         )
         for item in inventory_item_templates:
             item.save()
@@ -1741,9 +1807,30 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         Platform.objects.bulk_create(platforms)
 
         devices = (
-            Device(name='Device 1', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]),
-            Device(name='Device 2', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]),
-            Device(name='Device 3', site=sites[0], rack=racks[0], device_type=devicetypes[0], role=roles[0], platform=platforms[0]),
+            Device(
+                name='Device 1',
+                site=sites[0],
+                rack=racks[0],
+                device_type=devicetypes[0],
+                role=roles[0],
+                platform=platforms[0],
+            ),
+            Device(
+                name='Device 2',
+                site=sites[0],
+                rack=racks[0],
+                device_type=devicetypes[0],
+                role=roles[0],
+                platform=platforms[0],
+            ),
+            Device(
+                name='Device 3',
+                site=sites[0],
+                rack=racks[0],
+                device_type=devicetypes[0],
+                role=roles[0],
+                platform=platforms[0],
+            ),
         )
         Device.objects.bulk_create(devices)
 
@@ -1778,10 +1865,22 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         }
 
         cls.csv_data = (
-            "role,manufacturer,device_type,status,name,site,location,rack,position,face,virtual_chassis,vc_position,vc_priority",
-            "Device Role 1,Manufacturer 1,Device Type 1,active,Device 4,Site 1,Location 1,Rack 1,10,front,Virtual Chassis 1,1,10",
-            "Device Role 1,Manufacturer 1,Device Type 1,active,Device 5,Site 1,Location 1,Rack 1,20,front,Virtual Chassis 1,2,20",
-            "Device Role 1,Manufacturer 1,Device Type 1,active,Device 6,Site 1,Location 1,Rack 1,30,front,Virtual Chassis 1,3,30",
+            (
+                "role,manufacturer,device_type,status,name,site,location,rack,position,face,virtual_chassis,"
+                "vc_position,vc_priority"
+            ),
+            (
+                "Device Role 1,Manufacturer 1,Device Type 1,active,Device 4,Site 1,Location 1,Rack 1,10,front,"
+                "Virtual Chassis 1,1,10"
+            ),
+            (
+                "Device Role 1,Manufacturer 1,Device Type 1,active,Device 5,Site 1,Location 1,Rack 1,20,front,"
+                "Virtual Chassis 1,2,20"
+            ),
+            (
+                "Device Role 1,Manufacturer 1,Device Type 1,active,Device 6,Site 1,Location 1,Rack 1,30,front,"
+                "Virtual Chassis 1,3,30"
+            ),
         )
 
         cls.csv_update_data = (
@@ -2884,9 +2983,15 @@ class InventoryItemTestCase(ViewTestCases.DeviceComponentViewTestCase):
         )
         InventoryItemRole.objects.bulk_create(roles)
 
-        inventory_item1 = InventoryItem.objects.create(device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer)
-        inventory_item2 = InventoryItem.objects.create(device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer)
-        inventory_item3 = InventoryItem.objects.create(device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer)
+        inventory_item1 = InventoryItem.objects.create(
+            device=device, name='Inventory Item 1', role=roles[0], manufacturer=manufacturer
+        )
+        inventory_item2 = InventoryItem.objects.create(
+            device=device, name='Inventory Item 2', role=roles[0], manufacturer=manufacturer
+        )
+        inventory_item3 = InventoryItem.objects.create(
+            device=device, name='Inventory Item 3', role=roles[0], manufacturer=manufacturer
+        )
 
         tags = create_tags('Alpha', 'Bravo', 'Charlie')
 

+ 12 - 4
netbox/dcim/views.py

@@ -244,7 +244,9 @@ class RegionView(GetRelatedModelsMixin, generic.ObjectView):
                     (Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
                     (Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
                     (
-                        Circuit.objects.restrict(request.user, 'view').filter(terminations___region=instance).distinct(),
+                        Circuit.objects.restrict(request.user, 'view').filter(
+                            terminations___region=instance
+                        ).distinct(),
                         'region_id'
                     ),
                 ),
@@ -335,7 +337,9 @@ class SiteGroupView(GetRelatedModelsMixin, generic.ObjectView):
                     (Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
                     (Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
                     (
-                        Circuit.objects.restrict(request.user, 'view').filter(terminations___site_group=instance).distinct(),
+                        Circuit.objects.restrict(request.user, 'view').filter(
+                            terminations___site_group=instance
+                        ).distinct(),
                         'site_group_id'
                     ),
                 ),
@@ -507,7 +511,9 @@ class LocationView(GetRelatedModelsMixin, generic.ObjectView):
                 [CableTermination],
                 (
                     (
-                        Circuit.objects.restrict(request.user, 'view').filter(terminations___location=instance).distinct(),
+                        Circuit.objects.restrict(request.user, 'view').filter(
+                            terminations___location=instance
+                        ).distinct(),
                         'location_id'
                     ),
                 ),
@@ -3729,7 +3735,9 @@ class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMix
 
                 membership_form.save()
                 messages.success(request, mark_safe(
-                    _('Added member <a href="{url}">{device}</a>').format(url=device.get_absolute_url(), device=escape(device))
+                    _('Added member <a href="{url}">{device}</a>').format(
+                        url=device.get_absolute_url(), device=escape(device)
+                    )
                 ))
 
                 if '_addanother' in request.POST:

+ 2 - 1
netbox/extras/management/commands/reindex.py

@@ -53,7 +53,8 @@ class Command(BaseCommand):
 
                 else:
                     raise CommandError(
-                        f"Invalid model: {label}. Model names must be in the format <app_label> or <app_label>.<model_name>."
+                        f"Invalid model: {label}. Model names must be in the format <app_label> or "
+                        f"<app_label>.<model_name>."
                     )
 
         return indexers

+ 98 - 16
netbox/extras/migrations/0001_squashed.py

@@ -9,7 +9,6 @@ import utilities.validators
 
 
 class Migration(migrations.Migration):
-
     initial = True
 
     dependencies = [
@@ -99,8 +98,22 @@ class Migration(migrations.Migration):
             fields=[
                 ('object_id', models.IntegerField(db_index=True)),
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
-                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_tagged_items', to='contenttypes.contenttype')),
-                ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(app_label)s_%(class)s_items', to='extras.tag')),
+                (
+                    'content_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='%(app_label)s_%(class)s_tagged_items',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
+                (
+                    'tag',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='%(app_label)s_%(class)s_items',
+                        to='extras.tag',
+                    ),
+                ),
             ],
         ),
         migrations.CreateModel(
@@ -116,9 +129,32 @@ class Migration(migrations.Migration):
                 ('object_repr', models.CharField(editable=False, max_length=200)),
                 ('prechange_data', models.JSONField(blank=True, editable=False, null=True)),
                 ('postchange_data', models.JSONField(blank=True, editable=False, null=True)),
-                ('changed_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                ('related_object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='changes', to=settings.AUTH_USER_MODEL)),
+                (
+                    'changed_object_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'
+                    ),
+                ),
+                (
+                    'related_object_type',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
+                (
+                    'user',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='changes',
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
             ],
             options={
                 'ordering': ['-time'],
@@ -133,8 +169,16 @@ class Migration(migrations.Migration):
                 ('created', models.DateTimeField(auto_now_add=True)),
                 ('kind', models.CharField(default='info', max_length=30)),
                 ('comments', models.TextField()),
-                ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
-                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+                (
+                    'assigned_object_type',
+                    models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'),
+                ),
+                (
+                    'created_by',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL
+                    ),
+                ),
             ],
             options={
                 'verbose_name_plural': 'journal entries',
@@ -151,8 +195,24 @@ class Migration(migrations.Migration):
                 ('status', models.CharField(default='pending', max_length=30)),
                 ('data', models.JSONField(blank=True, null=True)),
                 ('job_id', models.UUIDField(unique=True)),
-                ('obj_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='job_results', to='contenttypes.contenttype')),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
+                (
+                    'obj_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='job_results',
+                        to='contenttypes.contenttype',
+                    ),
+                ),
+                (
+                    'user',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
             ],
             options={
                 'ordering': ['obj_type', 'name', '-created'],
@@ -163,12 +223,20 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.BigAutoField(primary_key=True, serialize=False)),
                 ('object_id', models.PositiveIntegerField()),
-                ('image', models.ImageField(height_field='image_height', upload_to=extras.utils.image_upload, width_field='image_width')),
+                (
+                    'image',
+                    models.ImageField(
+                        height_field='image_height', upload_to=extras.utils.image_upload, width_field='image_width'
+                    ),
+                ),
                 ('image_height', models.PositiveSmallIntegerField()),
                 ('image_width', models.PositiveSmallIntegerField()),
                 ('name', models.CharField(blank=True, max_length=50)),
                 ('created', models.DateTimeField(auto_now_add=True)),
-                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+                (
+                    'content_type',
+                    models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'),
+                ),
             ],
             options={
                 'ordering': ('name', 'pk'),
@@ -184,7 +252,10 @@ class Migration(migrations.Migration):
                 ('mime_type', models.CharField(blank=True, max_length=50)),
                 ('file_extension', models.CharField(blank=True, max_length=15)),
                 ('as_attachment', models.BooleanField(default=True)),
-                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+                (
+                    'content_type',
+                    models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'),
+                ),
             ],
             options={
                 'ordering': ['content_type', 'name'],
@@ -201,7 +272,10 @@ class Migration(migrations.Migration):
                 ('group_name', models.CharField(blank=True, max_length=50)),
                 ('button_class', models.CharField(default='default', max_length=30)),
                 ('new_window', models.BooleanField(default=False)),
-                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+                (
+                    'content_type',
+                    models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'),
+                ),
             ],
             options={
                 'ordering': ['group_name', 'weight', 'name'],
@@ -221,8 +295,16 @@ class Migration(migrations.Migration):
                 ('weight', models.PositiveSmallIntegerField(default=100)),
                 ('validation_minimum', models.PositiveIntegerField(blank=True, null=True)),
                 ('validation_maximum', models.PositiveIntegerField(blank=True, null=True)),
-                ('validation_regex', models.CharField(blank=True, max_length=500, validators=[utilities.validators.validate_regex])),
-                ('choices', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), blank=True, null=True, size=None)),
+                (
+                    'validation_regex',
+                    models.CharField(blank=True, max_length=500, validators=[utilities.validators.validate_regex]),
+                ),
+                (
+                    'choices',
+                    django.contrib.postgres.fields.ArrayField(
+                        base_field=models.CharField(max_length=100), blank=True, null=True, size=None
+                    ),
+                ),
                 ('content_types', models.ManyToManyField(related_name='custom_fields', to='contenttypes.ContentType')),
             ],
             options={

+ 0 - 1
netbox/extras/migrations/0002_squashed_0059.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('dcim', '0002_auto_20160622_1821'),
         ('extras', '0001_initial'),

+ 109 - 18
netbox/extras/migrations/0060_squashed_0086.py

@@ -12,7 +12,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('extras', '0060_customlink_button_class'),
         ('extras', '0061_extras_change_logging'),
@@ -40,7 +39,7 @@ class Migration(migrations.Migration):
         ('extras', '0083_search'),
         ('extras', '0084_staging'),
         ('extras', '0085_synced_data'),
-        ('extras', '0086_configtemplate')
+        ('extras', '0086_configtemplate'),
     ]
 
     dependencies = [
@@ -114,7 +113,23 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='customfield',
             name='name',
-            field=models.CharField(max_length=50, unique=True, validators=[django.core.validators.RegexValidator(flags=re.RegexFlag['IGNORECASE'], message='Only alphanumeric characters and underscores are allowed.', regex='^[a-z0-9_]+$'), django.core.validators.RegexValidator(flags=re.RegexFlag['IGNORECASE'], inverse_match=True, message='Double underscores are not permitted in custom field names.', regex='__')]),
+            field=models.CharField(
+                max_length=50,
+                unique=True,
+                validators=[
+                    django.core.validators.RegexValidator(
+                        flags=re.RegexFlag['IGNORECASE'],
+                        message='Only alphanumeric characters and underscores are allowed.',
+                        regex='^[a-z0-9_]+$',
+                    ),
+                    django.core.validators.RegexValidator(
+                        flags=re.RegexFlag['IGNORECASE'],
+                        inverse_match=True,
+                        message='Double underscores are not permitted in custom field names.',
+                        regex='__',
+                    ),
+                ],
+            ),
         ),
         migrations.AlterField(
             model_name='customfield',
@@ -134,7 +149,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='customfield',
             name='object_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'
+            ),
         ),
         migrations.AddField(
             model_name='customlink',
@@ -314,11 +331,16 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='exporttemplate',
-            constraint=models.UniqueConstraint(fields=('content_type', 'name'), name='extras_exporttemplate_unique_content_type_name'),
+            constraint=models.UniqueConstraint(
+                fields=('content_type', 'name'), name='extras_exporttemplate_unique_content_type_name'
+            ),
         ),
         migrations.AddConstraint(
             model_name='webhook',
-            constraint=models.UniqueConstraint(fields=('payload_url', 'type_create', 'type_update', 'type_delete'), name='extras_webhook_unique_payload_url_types'),
+            constraint=models.UniqueConstraint(
+                fields=('payload_url', 'type_create', 'type_update', 'type_delete'),
+                name='extras_webhook_unique_payload_url_types',
+            ),
         ),
         migrations.AddField(
             model_name='jobresult',
@@ -328,7 +350,9 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='jobresult',
             name='interval',
-            field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]),
+            field=models.PositiveIntegerField(
+                blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)]
+            ),
         ),
         migrations.AddField(
             model_name='jobresult',
@@ -379,7 +403,12 @@ class Migration(migrations.Migration):
                 ('shared', models.BooleanField(default=True)),
                 ('parameters', models.JSONField()),
                 ('content_types', models.ManyToManyField(related_name='saved_filters', to='contenttypes.contenttype')),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+                (
+                    'user',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL
+                    ),
+                ),
             ],
             options={
                 'ordering': ('weight', 'name'),
@@ -400,7 +429,12 @@ class Migration(migrations.Migration):
                 ('type', models.CharField(max_length=30)),
                 ('value', extras.fields.CachedValueField()),
                 ('weight', models.PositiveSmallIntegerField(default=1000)),
-                ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')),
+                (
+                    'object_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'
+                    ),
+                ),
             ],
             options={
                 'ordering': ('weight', 'object_type', 'object_id'),
@@ -414,7 +448,12 @@ class Migration(migrations.Migration):
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
-                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+                (
+                    'user',
+                    models.ForeignKey(
+                        blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL
+                    ),
+                ),
             ],
             options={
                 'ordering': ('name',),
@@ -429,8 +468,18 @@ class Migration(migrations.Migration):
                 ('action', models.CharField(max_length=20)),
                 ('object_id', models.PositiveBigIntegerField(blank=True, null=True)),
                 ('data', models.JSONField(blank=True, null=True)),
-                ('branch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staged_changes', to='extras.branch')),
-                ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')),
+                (
+                    'branch',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='staged_changes', to='extras.branch'
+                    ),
+                ),
+                (
+                    'object_type',
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'
+                    ),
+                ),
             ],
             options={
                 'ordering': ('pk',),
@@ -439,7 +488,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='configcontext',
             name='data_file',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='core.datafile',
+            ),
         ),
         migrations.AddField(
             model_name='configcontext',
@@ -449,7 +504,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='configcontext',
             name='data_source',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='+',
+                to='core.datasource',
+            ),
         ),
         migrations.AddField(
             model_name='configcontext',
@@ -464,7 +525,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='exporttemplate',
             name='data_file',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                related_name='+',
+                to='core.datafile',
+            ),
         ),
         migrations.AddField(
             model_name='exporttemplate',
@@ -474,7 +541,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='exporttemplate',
             name='data_source',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='+',
+                to='core.datasource',
+            ),
         ),
         migrations.AddField(
             model_name='exporttemplate',
@@ -498,8 +571,26 @@ class Migration(migrations.Migration):
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('template_code', models.TextField()),
                 ('environment_params', models.JSONField(blank=True, default=dict, null=True)),
-                ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')),
-                ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')),
+                (
+                    'data_file',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name='+',
+                        to='core.datafile',
+                    ),
+                ),
+                (
+                    'data_source',
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.PROTECT,
+                        related_name='+',
+                        to='core.datasource',
+                    ),
+                ),
                 ('auto_sync_enabled', models.BooleanField(default=False)),
                 ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
             ],

+ 36 - 11
netbox/extras/migrations/0087_squashed_0098.py

@@ -9,7 +9,6 @@ import utilities.json
 
 
 class Migration(migrations.Migration):
-
     replaces = [
         ('extras', '0087_dashboard'),
         ('extras', '0088_jobresult_webhooks'),
@@ -22,7 +21,7 @@ class Migration(migrations.Migration):
         ('extras', '0095_bookmarks'),
         ('extras', '0096_customfieldchoiceset'),
         ('extras', '0097_customfield_remove_choices'),
-        ('extras', '0098_webhook_custom_field_data_webhook_tags')
+        ('extras', '0098_webhook_custom_field_data_webhook_tags'),
     ]
 
     dependencies = [
@@ -39,7 +38,14 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('layout', models.JSONField(default=list)),
                 ('config', models.JSONField(default=dict)),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='dashboard', to=settings.AUTH_USER_MODEL)),
+                (
+                    'user',
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='dashboard',
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
             ],
         ),
         migrations.AddField(
@@ -64,8 +70,7 @@ class Migration(migrations.Migration):
         ),
         migrations.CreateModel(
             name='ReportModule',
-            fields=[
-            ],
+            fields=[],
             options={
                 'proxy': True,
                 'ordering': ('file_root', 'file_path'),
@@ -76,8 +81,7 @@ class Migration(migrations.Migration):
         ),
         migrations.CreateModel(
             name='ScriptModule',
-            fields=[
-            ],
+            fields=[],
             options={
                 'proxy': True,
                 'ordering': ('file_root', 'file_path'),
@@ -108,7 +112,10 @@ class Migration(migrations.Migration):
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('created', models.DateTimeField(auto_now_add=True)),
                 ('object_id', models.PositiveBigIntegerField()),
-                ('object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')),
+                (
+                    'object_type',
+                    models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype'),
+                ),
                 ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
             ],
             options={
@@ -117,7 +124,9 @@ class Migration(migrations.Migration):
         ),
         migrations.AddConstraint(
             model_name='bookmark',
-            constraint=models.UniqueConstraint(fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user'),
+            constraint=models.UniqueConstraint(
+                fields=('object_type', 'object_id', 'user'), name='extras_bookmark_unique_per_object_and_user'
+            ),
         ),
         migrations.CreateModel(
             name='CustomFieldChoiceSet',
@@ -128,7 +137,17 @@ class Migration(migrations.Migration):
                 ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('base_choices', models.CharField(blank=True, max_length=50)),
-                ('extra_choices', django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), size=2), blank=True, null=True, size=None)),
+                (
+                    'extra_choices',
+                    django.contrib.postgres.fields.ArrayField(
+                        base_field=django.contrib.postgres.fields.ArrayField(
+                            base_field=models.CharField(max_length=100), size=2
+                        ),
+                        blank=True,
+                        null=True,
+                        size=None,
+                    ),
+                ),
                 ('order_alphabetically', models.BooleanField(default=False)),
             ],
             options={
@@ -138,7 +157,13 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='customfield',
             name='choice_set',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='choices_for', to='extras.customfieldchoiceset'),
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                related_name='choices_for',
+                to='extras.customfieldchoiceset',
+            ),
         ),
         migrations.RemoveField(
             model_name='customfield',

+ 0 - 1
netbox/extras/migrations/0099_cachedvalue_ordering.py

@@ -4,7 +4,6 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0098_webhook_custom_field_data_webhook_tags'),
     ]

+ 1 - 5
netbox/extras/migrations/0100_customfield_ui_attrs.py

@@ -14,7 +14,6 @@ def update_ui_attrs(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0099_cachedvalue_ordering'),
     ]
@@ -30,10 +29,7 @@ class Migration(migrations.Migration):
             name='ui_visible',
             field=models.CharField(default='always', max_length=50),
         ),
-        migrations.RunPython(
-            code=update_ui_attrs,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_ui_attrs, reverse_code=migrations.RunPython.noop),
         migrations.RemoveField(
             model_name='customfield',
             name='ui_visibility',

+ 5 - 7
netbox/extras/migrations/0101_eventrule.py

@@ -8,8 +8,8 @@ from extras.choices import *
 
 
 def move_webhooks(apps, schema_editor):
-    Webhook = apps.get_model("extras", "Webhook")
-    EventRule = apps.get_model("extras", "EventRule")
+    Webhook = apps.get_model('extras', 'Webhook')
+    EventRule = apps.get_model('extras', 'EventRule')
 
     webhook_ct = ContentType.objects.get_for_model(Webhook).pk
     for webhook in Webhook.objects.all():
@@ -39,7 +39,6 @@ class Migration(migrations.Migration):
     ]
 
     operations = [
-
         # Create the EventRule model
         migrations.CreateModel(
             name='EventRule',
@@ -93,12 +92,12 @@ class Migration(migrations.Migration):
         ),
         migrations.AddIndex(
             model_name='eventrule',
-            index=models.Index(fields=['action_object_type', 'action_object_id'], name='extras_even_action__d9e2af_idx'),
+            index=models.Index(
+                fields=['action_object_type', 'action_object_id'], name='extras_even_action__d9e2af_idx'
+            ),
         ),
-
         # Replicate Webhook data
         migrations.RunPython(move_webhooks),
-
         # Remove obsolete fields from Webhook
         migrations.RemoveConstraint(
             model_name='webhook',
@@ -136,7 +135,6 @@ class Migration(migrations.Migration):
             model_name='webhook',
             name='type_update',
         ),
-
         # Add description field to Webhook
         migrations.AddField(
             model_name='webhook',

+ 1 - 5
netbox/extras/migrations/0102_move_configrevision.py

@@ -13,7 +13,6 @@ def update_content_type(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0101_eventrule'),
     ]
@@ -32,8 +31,5 @@ class Migration(migrations.Migration):
                 ),
             ],
         ),
-        migrations.RunPython(
-            code=update_content_type,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_content_type, reverse_code=migrations.RunPython.noop),
     ]

+ 9 - 4
netbox/extras/migrations/0103_gfk_indexes.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0102_move_configrevision'),
     ]
@@ -20,15 +19,21 @@ class Migration(migrations.Migration):
         ),
         migrations.AddIndex(
             model_name='journalentry',
-            index=models.Index(fields=['assigned_object_type', 'assigned_object_id'], name='extras_jour_assigne_76510f_idx'),
+            index=models.Index(
+                fields=['assigned_object_type', 'assigned_object_id'], name='extras_jour_assigne_76510f_idx'
+            ),
         ),
         migrations.AddIndex(
             model_name='objectchange',
-            index=models.Index(fields=['changed_object_type', 'changed_object_id'], name='extras_obje_changed_927fe5_idx'),
+            index=models.Index(
+                fields=['changed_object_type', 'changed_object_id'], name='extras_obje_changed_927fe5_idx'
+            ),
         ),
         migrations.AddIndex(
             model_name='objectchange',
-            index=models.Index(fields=['related_object_type', 'related_object_id'], name='extras_obje_related_bfcdef_idx'),
+            index=models.Index(
+                fields=['related_object_type', 'related_object_id'], name='extras_obje_related_bfcdef_idx'
+            ),
         ),
         migrations.AddIndex(
             model_name='stagedchange',

+ 0 - 1
netbox/extras/migrations/0105_customfield_min_max_values.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0104_stagedchange_remove_change_logging'),
     ]

+ 0 - 1
netbox/extras/migrations/0106_bookmark_user_cascade_deletion.py

@@ -6,7 +6,6 @@ import django.db.models.deletion
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
         ('extras', '0105_customfield_min_max_values'),

+ 0 - 1
netbox/extras/migrations/0107_cachedvalue_extras_cachedvalue_object.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0106_bookmark_user_cascade_deletion'),
     ]

+ 1 - 5
netbox/extras/migrations/0108_convert_reports_to_scripts.py

@@ -12,16 +12,12 @@ def convert_reportmodule_jobs(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0107_cachedvalue_extras_cachedvalue_object'),
     ]
 
     operations = [
-        migrations.RunPython(
-            code=convert_reportmodule_jobs,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=convert_reportmodule_jobs, reverse_code=migrations.RunPython.noop),
         migrations.DeleteModel(
             name='Report',
         ),

+ 21 - 25
netbox/extras/migrations/0109_script_model.py

@@ -55,9 +55,10 @@ def get_module_scripts(scriptmodule):
     """
     Return a dictionary mapping of name and script class inside the passed ScriptModule.
     """
+
     def get_name(cls):
         # For child objects in submodules use the full import path w/o the root module as the name
-        return cls.full_name.split(".", maxsplit=1)[1]
+        return cls.full_name.split('.', maxsplit=1)[1]
 
     loader = SourceFileLoader(get_python_name(scriptmodule), get_full_path(scriptmodule))
     try:
@@ -100,17 +101,13 @@ def update_scripts(apps, schema_editor):
             )
 
             # Update all Jobs associated with this ScriptModule & script name to point to the new Script object
-            Job.objects.filter(
-                object_type_id=scriptmodule_ct.id,
-                object_id=module.pk,
-                name=script_name
-            ).update(object_type_id=script_ct.id, object_id=script.pk)
+            Job.objects.filter(object_type_id=scriptmodule_ct.id, object_id=module.pk, name=script_name).update(
+                object_type_id=script_ct.id, object_id=script.pk
+            )
             # Update all Jobs associated with this ScriptModule & script name to point to the new Script object
-            Job.objects.filter(
-                object_type_id=reportmodule_ct.id,
-                object_id=module.pk,
-                name=script_name
-            ).update(object_type_id=script_ct.id, object_id=script.pk)
+            Job.objects.filter(object_type_id=reportmodule_ct.id, object_id=module.pk, name=script_name).update(
+                object_type_id=script_ct.id, object_id=script.pk
+            )
 
 
 def update_event_rules(apps, schema_editor):
@@ -129,15 +126,12 @@ def update_event_rules(apps, schema_editor):
     for eventrule in EventRule.objects.filter(action_object_type=scriptmodule_ct):
         name = eventrule.action_parameters.get('script_name')
         obj, __ = Script.objects.get_or_create(
-            module_id=eventrule.action_object_id,
-            name=name,
-            defaults={'is_executable': False}
+            module_id=eventrule.action_object_id, name=name, defaults={'is_executable': False}
         )
         EventRule.objects.filter(pk=eventrule.pk).update(action_object_type=script_ct, action_object_id=obj.id)
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0108_convert_reports_to_scripts'),
     ]
@@ -148,8 +142,16 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                 ('name', models.CharField(editable=False, max_length=79)),
-                ('module', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='scripts', to='extras.scriptmodule')),
-                ('is_executable', models.BooleanField(editable=False, default=True))
+                (
+                    'module',
+                    models.ForeignKey(
+                        editable=False,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name='scripts',
+                        to='extras.scriptmodule',
+                    ),
+                ),
+                ('is_executable', models.BooleanField(editable=False, default=True)),
             ],
             options={
                 'ordering': ('module', 'name'),
@@ -159,12 +161,6 @@ class Migration(migrations.Migration):
             model_name='script',
             constraint=models.UniqueConstraint(fields=('name', 'module'), name='extras_script_unique_name_module'),
         ),
-        migrations.RunPython(
-            code=update_scripts,
-            reverse_code=migrations.RunPython.noop
-        ),
-        migrations.RunPython(
-            code=update_event_rules,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_scripts, reverse_code=migrations.RunPython.noop),
+        migrations.RunPython(code=update_event_rules, reverse_code=migrations.RunPython.noop),
     ]

+ 0 - 1
netbox/extras/migrations/0110_remove_eventrule_action_parameters.py

@@ -2,7 +2,6 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0109_script_model'),
     ]

+ 16 - 18
netbox/extras/migrations/0111_rename_content_types.py

@@ -3,7 +3,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0010_gfk_indexes'),
         ('extras', '0110_remove_eventrule_action_parameters'),
@@ -24,16 +23,19 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='customfield',
             name='object_type',
-            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='core.objecttype'),
-        ),
-        migrations.RunSQL(
-            "ALTER TABLE IF EXISTS extras_customfield_content_types_id_seq RENAME TO extras_customfield_object_types_id_seq"
-        ),
+            field=models.ForeignKey(
+                blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='core.objecttype'
+            ),
+        ),
+        migrations.RunSQL((
+            'ALTER TABLE IF EXISTS extras_customfield_content_types_id_seq '
+            'RENAME TO extras_customfield_object_types_id_seq'
+        )),
         # Pre-v2.10 sequence name (see #15605)
-        migrations.RunSQL(
-            "ALTER TABLE IF EXISTS extras_customfield_obj_type_id_seq RENAME TO extras_customfield_object_types_id_seq"
-        ),
-
+        migrations.RunSQL((
+            'ALTER TABLE IF EXISTS extras_customfield_obj_type_id_seq '
+            'RENAME TO extras_customfield_object_types_id_seq'
+        )),
         # Custom links
         migrations.RenameField(
             model_name='customlink',
@@ -46,9 +48,8 @@ class Migration(migrations.Migration):
             field=models.ManyToManyField(related_name='custom_links', to='core.objecttype'),
         ),
         migrations.RunSQL(
-            "ALTER TABLE extras_customlink_content_types_id_seq RENAME TO extras_customlink_object_types_id_seq"
+            'ALTER TABLE extras_customlink_content_types_id_seq RENAME TO extras_customlink_object_types_id_seq'
         ),
-
         # Event rules
         migrations.RenameField(
             model_name='eventrule',
@@ -61,9 +62,8 @@ class Migration(migrations.Migration):
             field=models.ManyToManyField(related_name='event_rules', to='core.objecttype'),
         ),
         migrations.RunSQL(
-            "ALTER TABLE extras_eventrule_content_types_id_seq RENAME TO extras_eventrule_object_types_id_seq"
+            'ALTER TABLE extras_eventrule_content_types_id_seq RENAME TO extras_eventrule_object_types_id_seq'
         ),
-
         # Export templates
         migrations.RenameField(
             model_name='exporttemplate',
@@ -76,9 +76,8 @@ class Migration(migrations.Migration):
             field=models.ManyToManyField(related_name='export_templates', to='core.objecttype'),
         ),
         migrations.RunSQL(
-            "ALTER TABLE extras_exporttemplate_content_types_id_seq RENAME TO extras_exporttemplate_object_types_id_seq"
+            'ALTER TABLE extras_exporttemplate_content_types_id_seq RENAME TO extras_exporttemplate_object_types_id_seq'
         ),
-
         # Saved filters
         migrations.RenameField(
             model_name='savedfilter',
@@ -91,9 +90,8 @@ class Migration(migrations.Migration):
             field=models.ManyToManyField(related_name='saved_filters', to='core.objecttype'),
         ),
         migrations.RunSQL(
-            "ALTER TABLE extras_savedfilter_content_types_id_seq RENAME TO extras_savedfilter_object_types_id_seq"
+            'ALTER TABLE extras_savedfilter_content_types_id_seq RENAME TO extras_savedfilter_object_types_id_seq'
         ),
-
         # Image attachments
         migrations.RemoveIndex(
             model_name='imageattachment',

+ 0 - 1
netbox/extras/migrations/0112_tag_update_object_types.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('core', '0010_gfk_indexes'),
         ('extras', '0111_rename_content_types'),

+ 0 - 1
netbox/extras/migrations/0113_customfield_rename_object_type.py

@@ -2,7 +2,6 @@ from django.db import migrations
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0112_tag_update_object_types'),
     ]

+ 0 - 1
netbox/extras/migrations/0114_customfield_add_comments.py

@@ -4,7 +4,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0113_customfield_rename_object_type'),
     ]

+ 1 - 5
netbox/extras/migrations/0115_convert_dashboard_widgets.py

@@ -16,14 +16,10 @@ def update_dashboard_widgets(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0114_customfield_add_comments'),
     ]
 
     operations = [
-        migrations.RunPython(
-            code=update_dashboard_widgets,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_dashboard_widgets, reverse_code=migrations.RunPython.noop),
     ]

+ 1 - 5
netbox/extras/migrations/0116_custom_link_button_color.py

@@ -7,7 +7,6 @@ def update_link_buttons(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0115_convert_dashboard_widgets'),
     ]
@@ -18,8 +17,5 @@ class Migration(migrations.Migration):
             name='button_class',
             field=models.CharField(default='default', max_length=30),
         ),
-        migrations.RunPython(
-            code=update_link_buttons,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_link_buttons, reverse_code=migrations.RunPython.noop),
     ]

+ 31 - 49
netbox/extras/migrations/0117_move_objectchange.py

@@ -26,7 +26,6 @@ def update_dashboard_widgets(apps, schema_editor):
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0116_custom_link_button_color'),
         ('core', '0011_move_objectchange'),
@@ -44,81 +43,64 @@ class Migration(migrations.Migration):
                     name='ObjectChange',
                     table='core_objectchange',
                 ),
-
                 # Rename PK sequence
-                migrations.RunSQL(
-                    "ALTER TABLE extras_objectchange_id_seq"
-                    "  RENAME TO core_objectchange_id_seq"
-                ),
-
+                migrations.RunSQL('ALTER TABLE extras_objectchange_id_seq' '  RENAME TO core_objectchange_id_seq'),
                 # Rename indexes. Hashes generated by schema_editor._create_index_name()
+                migrations.RunSQL('ALTER INDEX extras_objectchange_pkey' '  RENAME TO core_objectchange_pkey'),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_pkey"
-                    "  RENAME TO core_objectchange_pkey"
+                    'ALTER INDEX extras_obje_changed_927fe5_idx'
+                    '  RENAME TO core_objectchange_changed_object_type_id_cha_79a9ed1e'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_obje_changed_927fe5_idx"
-                    "  RENAME TO core_objectchange_changed_object_type_id_cha_79a9ed1e"
+                    'ALTER INDEX extras_obje_related_bfcdef_idx'
+                    '  RENAME TO core_objectchange_related_object_type_id_rel_a71d604a'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_obje_related_bfcdef_idx"
-                    "  RENAME TO core_objectchange_related_object_type_id_rel_a71d604a"
+                    'ALTER INDEX extras_objectchange_changed_object_type_id_b755bb60'
+                    '  RENAME TO core_objectchange_changed_object_type_id_2070ade6'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_changed_object_type_id_b755bb60"
-                    "  RENAME TO core_objectchange_changed_object_type_id_2070ade6"
+                    'ALTER INDEX extras_objectchange_related_object_type_id_fe6e521f'
+                    '  RENAME TO core_objectchange_related_object_type_id_b80958af'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_related_object_type_id_fe6e521f"
-                    "  RENAME TO core_objectchange_related_object_type_id_b80958af"
+                    'ALTER INDEX extras_objectchange_request_id_4ae21e90'
+                    '  RENAME TO core_objectchange_request_id_d9d160ac'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_request_id_4ae21e90"
-                    "  RENAME TO core_objectchange_request_id_d9d160ac"
+                    'ALTER INDEX extras_objectchange_time_224380ea' '  RENAME TO core_objectchange_time_800f60a5'
                 ),
                 migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_time_224380ea"
-                    "  RENAME TO core_objectchange_time_800f60a5"
+                    'ALTER INDEX extras_objectchange_user_id_7fdf8186' '  RENAME TO core_objectchange_user_id_2b2142be'
                 ),
-                migrations.RunSQL(
-                    "ALTER INDEX extras_objectchange_user_id_7fdf8186"
-                    "  RENAME TO core_objectchange_user_id_2b2142be"
-                ),
-
                 # Rename constraints
                 migrations.RunSQL(
-                    "ALTER TABLE core_objectchange RENAME CONSTRAINT "
-                    "extras_objectchange_changed_object_id_check TO "
-                    "core_objectchange_changed_object_id_check"
+                    'ALTER TABLE core_objectchange RENAME CONSTRAINT '
+                    'extras_objectchange_changed_object_id_check TO '
+                    'core_objectchange_changed_object_id_check'
                 ),
                 migrations.RunSQL(
-                    "ALTER TABLE core_objectchange RENAME CONSTRAINT "
-                    "extras_objectchange_related_object_id_check TO "
-                    "core_objectchange_related_object_id_check"
+                    'ALTER TABLE core_objectchange RENAME CONSTRAINT '
+                    'extras_objectchange_related_object_id_check TO '
+                    'core_objectchange_related_object_id_check'
                 ),
                 migrations.RunSQL(
-                    "ALTER TABLE core_objectchange RENAME CONSTRAINT "
-                    "extras_objectchange_changed_object_type__b755bb60_fk_django_co TO "
-                    "core_objectchange_changed_object_type_id_2070ade6"
+                    'ALTER TABLE core_objectchange RENAME CONSTRAINT '
+                    'extras_objectchange_changed_object_type__b755bb60_fk_django_co TO '
+                    'core_objectchange_changed_object_type_id_2070ade6'
                 ),
                 migrations.RunSQL(
-                    "ALTER TABLE core_objectchange RENAME CONSTRAINT "
-                    "extras_objectchange_related_object_type__fe6e521f_fk_django_co TO "
-                    "core_objectchange_related_object_type_id_b80958af"
+                    'ALTER TABLE core_objectchange RENAME CONSTRAINT '
+                    'extras_objectchange_related_object_type__fe6e521f_fk_django_co TO '
+                    'core_objectchange_related_object_type_id_b80958af'
                 ),
                 migrations.RunSQL(
-                    "ALTER TABLE core_objectchange RENAME CONSTRAINT "
-                    "extras_objectchange_user_id_7fdf8186_fk_auth_user_id TO "
-                    "core_objectchange_user_id_2b2142be"
+                    'ALTER TABLE core_objectchange RENAME CONSTRAINT '
+                    'extras_objectchange_user_id_7fdf8186_fk_auth_user_id TO '
+                    'core_objectchange_user_id_2b2142be'
                 ),
             ],
         ),
-        migrations.RunPython(
-            code=update_content_types,
-            reverse_code=migrations.RunPython.noop
-        ),
-        migrations.RunPython(
-            code=update_dashboard_widgets,
-            reverse_code=migrations.RunPython.noop
-        ),
+        migrations.RunPython(code=update_content_types, reverse_code=migrations.RunPython.noop),
+        migrations.RunPython(code=update_dashboard_widgets, reverse_code=migrations.RunPython.noop),
     ]

+ 0 - 1
netbox/extras/migrations/0118_customfield_uniqueness.py

@@ -2,7 +2,6 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     dependencies = [
         ('extras', '0117_move_objectchange'),
     ]

Некоторые файлы не были показаны из-за большого количества измененных файлов