Преглед на файлове

Cache A/B termination devices on the Cable model

Jeremy Stretch преди 6 години
родител
ревизия
d2ab41abfb
променени са 2 файла, в които са добавени 68 реда и са изтрити 0 реда
  1. 46 0
      netbox/dcim/migrations/0075_cable_devices.py
  2. 22 0
      netbox/dcim/models.py

+ 46 - 0
netbox/dcim/migrations/0075_cable_devices.py

@@ -0,0 +1,46 @@
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+def cache_cable_devices(apps, schema_editor):
+    Cable = apps.get_model('dcim', 'Cable')
+
+    # Cache A/B termination devices on all existing Cables. Note that the custom save() method on Cable is not
+    # available during a migration, so we replicate its logic here.
+    for cable in Cable.objects.all():
+
+        termination_a_model = apps.get_model(cable.termination_a_type.app_label, cable.termination_a_type.model)
+        if hasattr(termination_a_model, 'device'):
+            termination_a = termination_a_model.objects.get(pk=cable.termination_a_id)
+            cable._termination_a_device = termination_a.device
+
+        termination_b_model = apps.get_model(cable.termination_b_type.app_label, cable.termination_b_type.model)
+        if hasattr(termination_b_model, 'device'):
+            termination_b = termination_b_model.objects.get(pk=cable.termination_b_id)
+            cable._termination_b_device = termination_b.device
+
+        cable.save()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0074_increase_field_length_platform_name_slug'),
+    ]
+
+    operations = [
+        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'),
+        ),
+        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'),
+        ),
+        migrations.RunPython(
+            code=cache_cable_devices,
+            reverse_code=migrations.RunPython.noop
+        ),
+    ]

+ 22 - 0
netbox/dcim/models.py

@@ -2781,6 +2781,22 @@ class Cable(ChangeLoggedModel):
         blank=True,
         blank=True,
         null=True
         null=True
     )
     )
+    # Cache the associated device (where applicable) for the A and B terminations. This enables filtering of Cables by
+    # their associated Devices.
+    _termination_a_device = models.ForeignKey(
+        to=Device,
+        on_delete=models.CASCADE,
+        related_name='+',
+        blank=True,
+        null=True
+    )
+    _termination_b_device = models.ForeignKey(
+        to=Device,
+        on_delete=models.CASCADE,
+        related_name='+',
+        blank=True,
+        null=True
+    )
 
 
     csv_headers = [
     csv_headers = [
         'termination_a_type', 'termination_a_id', 'termination_b_type', 'termination_b_id', 'type', 'status', 'label',
         'termination_a_type', 'termination_a_id', 'termination_b_type', 'termination_b_id', 'type', 'status', 'label',
@@ -2895,6 +2911,12 @@ class Cable(ChangeLoggedModel):
         if self.length and self.length_unit:
         if self.length and self.length_unit:
             self._abs_length = to_meters(self.length, self.length_unit)
             self._abs_length = to_meters(self.length, self.length_unit)
 
 
+        # Store the parent Device for the A and B terminations (if applicable) to enable filtering
+        if hasattr(self.termination_a, 'device'):
+            self._termination_a_device = self.termination_a.device
+        if hasattr(self.termination_b, 'device'):
+            self._termination_b_device = self.termination_b.device
+
         super().save(*args, **kwargs)
         super().save(*args, **kwargs)
 
 
     def to_csv(self):
     def to_csv(self):