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

Fixes #22662: Fix database overflow when saving Cables with large lengths (#22668)

Martin Hauser 1 неделя назад
Родитель
Сommit
bd562dd5c7

+ 16 - 0
netbox/dcim/migrations/0238_alter_cable__abs_length.py

@@ -0,0 +1,16 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0237_module_remove_local_context_data'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='cable',
+            name='_abs_length',
+            field=models.DecimalField(blank=True, decimal_places=4, max_digits=14, null=True),
+        ),
+    ]

+ 1 - 1
netbox/dcim/models/cables.py

@@ -133,7 +133,7 @@ class Cable(PrimaryModel):
     )
     # Stores the normalized length (in meters) for database ordering
     _abs_length = models.DecimalField(
-        max_digits=10,
+        max_digits=14,
         decimal_places=4,
         blank=True,
         null=True

+ 28 - 0
netbox/dcim/tests/test_models.py

@@ -1,3 +1,5 @@
+from decimal import Decimal
+
 from django.core.exceptions import ValidationError
 from django.db.models.signals import post_save
 from django.test import TestCase, tag
@@ -2227,6 +2229,32 @@ class CableTestCase(TestCase):
         interface = Interface(device=device, name='tmp', cable=cable)
         self.assertIsNone(interface.path)
 
+    def test_cable_length_normalization_large_kilometer_value(self):
+        """
+        A large kilometer length must pass validation and fit in the normalized length field.
+        """
+        cable = Cable.objects.first()
+        cable.length = Decimal('1234')
+        cable.length_unit = CableLengthUnitChoices.UNIT_KILOMETER
+        cable.full_clean()
+        cable.save()
+        cable.refresh_from_db()
+
+        self.assertEqual(cable._abs_length, Decimal('1234000.0000'))
+
+    def test_cable_length_normalization_maximum_mile_value(self):
+        """
+        The maximum length value expressed in miles must fit in the normalized length field.
+        """
+        cable = Cable.objects.first()
+        cable.length = Decimal('999999.99')
+        cable.length_unit = CableLengthUnitChoices.UNIT_MILE
+        cable.full_clean()
+        cable.save()
+        cable.refresh_from_db()
+
+        self.assertEqual(cable._abs_length, Decimal('1609343983.9066'))
+
 
 class CableTerminationTestCase(TestCase):