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

Fixes #3849: Fix ordering of models when dumping data to JSON

Jeremy Stretch 6 лет назад
Родитель
Сommit
e5c5a1a101
2 измененных файлов с 182 добавлено и 181 удалено
  1. 1 0
      docs/release-notes/version-2.6.md
  2. 181 181
      netbox/dcim/models.py

+ 1 - 0
docs/release-notes/version-2.6.md

@@ -14,6 +14,7 @@
 ## Bug Fixes
 ## Bug Fixes
 
 
 * [#3589](https://github.com/netbox-community/netbox/issues/3589) - Fix validation on tagged VLANs of an interface
 * [#3589](https://github.com/netbox-community/netbox/issues/3589) - Fix validation on tagged VLANs of an interface
+* [#3849](https://github.com/netbox-community/netbox/issues/3849) - Fix ordering of models when dumping data to JSON
 * [#3853](https://github.com/netbox-community/netbox/issues/3853) - Fix device role link on config context view
 * [#3853](https://github.com/netbox-community/netbox/issues/3853) - Fix device role link on config context view
 * [#3856](https://github.com/netbox-community/netbox/issues/3856) - Allow filtering VM interfaces by multiple MAC addresses
 * [#3856](https://github.com/netbox-community/netbox/issues/3856) - Allow filtering VM interfaces by multiple MAC addresses
 * [#3857](https://github.com/netbox-community/netbox/issues/3857) - Fix group custom links rendering
 * [#3857](https://github.com/netbox-community/netbox/issues/3857) - Fix group custom links rendering

+ 181 - 181
netbox/dcim/models.py

@@ -2755,6 +2755,187 @@ class VirtualChassis(ChangeLoggedModel):
         )
         )
 
 
 
 
+#
+# Power
+#
+
+class PowerPanel(ChangeLoggedModel):
+    """
+    A distribution point for electrical power; e.g. a data center RPP.
+    """
+    site = models.ForeignKey(
+        to='Site',
+        on_delete=models.PROTECT
+    )
+    rack_group = models.ForeignKey(
+        to='RackGroup',
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True
+    )
+    name = models.CharField(
+        max_length=50
+    )
+
+    csv_headers = ['site', 'rack_group_name', 'name']
+
+    class Meta:
+        ordering = ['site', 'name']
+        unique_together = ['site', 'name']
+
+    def __str__(self):
+        return self.name
+
+    def get_absolute_url(self):
+        return reverse('dcim:powerpanel', args=[self.pk])
+
+    def to_csv(self):
+        return (
+            self.site.name,
+            self.rack_group.name if self.rack_group else None,
+            self.name,
+        )
+
+    def clean(self):
+
+        # RackGroup must belong to assigned Site
+        if self.rack_group and self.rack_group.site != self.site:
+            raise ValidationError("Rack group {} ({}) is in a different site than {}".format(
+                self.rack_group, self.rack_group.site, self.site
+            ))
+
+
+class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel):
+    """
+    An electrical circuit delivered from a PowerPanel.
+    """
+    power_panel = models.ForeignKey(
+        to='PowerPanel',
+        on_delete=models.PROTECT,
+        related_name='powerfeeds'
+    )
+    rack = models.ForeignKey(
+        to='Rack',
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True
+    )
+    connected_endpoint = models.OneToOneField(
+        to='dcim.PowerPort',
+        on_delete=models.SET_NULL,
+        related_name='+',
+        blank=True,
+        null=True
+    )
+    connection_status = models.NullBooleanField(
+        choices=CONNECTION_STATUS_CHOICES,
+        blank=True
+    )
+    name = models.CharField(
+        max_length=50
+    )
+    status = models.PositiveSmallIntegerField(
+        choices=POWERFEED_STATUS_CHOICES,
+        default=POWERFEED_STATUS_ACTIVE
+    )
+    type = models.PositiveSmallIntegerField(
+        choices=POWERFEED_TYPE_CHOICES,
+        default=POWERFEED_TYPE_PRIMARY
+    )
+    supply = models.PositiveSmallIntegerField(
+        choices=POWERFEED_SUPPLY_CHOICES,
+        default=POWERFEED_SUPPLY_AC
+    )
+    phase = models.PositiveSmallIntegerField(
+        choices=POWERFEED_PHASE_CHOICES,
+        default=POWERFEED_PHASE_SINGLE
+    )
+    voltage = models.PositiveSmallIntegerField(
+        validators=[MinValueValidator(1)],
+        default=120
+    )
+    amperage = models.PositiveSmallIntegerField(
+        validators=[MinValueValidator(1)],
+        default=20
+    )
+    max_utilization = models.PositiveSmallIntegerField(
+        validators=[MinValueValidator(1), MaxValueValidator(100)],
+        default=80,
+        help_text="Maximum permissible draw (percentage)"
+    )
+    available_power = models.PositiveSmallIntegerField(
+        default=0,
+        editable=False
+    )
+    comments = models.TextField(
+        blank=True
+    )
+    custom_field_values = GenericRelation(
+        to='extras.CustomFieldValue',
+        content_type_field='obj_type',
+        object_id_field='obj_id'
+    )
+
+    tags = TaggableManager(through=TaggedItem)
+
+    csv_headers = [
+        'site', 'panel_name', 'rack_group', 'rack_name', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
+        'amperage', 'max_utilization', 'comments',
+    ]
+
+    class Meta:
+        ordering = ['power_panel', 'name']
+        unique_together = ['power_panel', 'name']
+
+    def __str__(self):
+        return self.name
+
+    def get_absolute_url(self):
+        return reverse('dcim:powerfeed', args=[self.pk])
+
+    def to_csv(self):
+        return (
+            self.power_panel.site.name,
+            self.power_panel.name,
+            self.rack.group.name if self.rack and self.rack.group else None,
+            self.rack.name if self.rack else None,
+            self.name,
+            self.get_status_display(),
+            self.get_type_display(),
+            self.get_supply_display(),
+            self.get_phase_display(),
+            self.voltage,
+            self.amperage,
+            self.max_utilization,
+            self.comments,
+        )
+
+    def clean(self):
+
+        # Rack must belong to same Site as PowerPanel
+        if self.rack and self.rack.site != self.power_panel.site:
+            raise ValidationError("Rack {} ({}) and power panel {} ({}) are in different sites".format(
+                self.rack, self.rack.site, self.power_panel, self.power_panel.site
+            ))
+
+    def save(self, *args, **kwargs):
+
+        # Cache the available_power property on the instance
+        kva = self.voltage * self.amperage * (self.max_utilization / 100)
+        if self.phase == POWERFEED_PHASE_3PHASE:
+            self.available_power = round(kva * 1.732)
+        else:
+            self.available_power = round(kva)
+
+        super().save(*args, **kwargs)
+
+    def get_type_class(self):
+        return STATUS_CLASSES[self.type]
+
+    def get_status_class(self):
+        return STATUS_CLASSES[self.status]
+
+
 #
 #
 # Cables
 # Cables
 #
 #
@@ -3008,184 +3189,3 @@ class Cable(ChangeLoggedModel):
         b_endpoint = b_path[-1][2]
         b_endpoint = b_path[-1][2]
 
 
         return a_endpoint, b_endpoint, path_status
         return a_endpoint, b_endpoint, path_status
-
-
-#
-# Power
-#
-
-class PowerPanel(ChangeLoggedModel):
-    """
-    A distribution point for electrical power; e.g. a data center RPP.
-    """
-    site = models.ForeignKey(
-        to='Site',
-        on_delete=models.PROTECT
-    )
-    rack_group = models.ForeignKey(
-        to='RackGroup',
-        on_delete=models.PROTECT,
-        blank=True,
-        null=True
-    )
-    name = models.CharField(
-        max_length=50
-    )
-
-    csv_headers = ['site', 'rack_group_name', 'name']
-
-    class Meta:
-        ordering = ['site', 'name']
-        unique_together = ['site', 'name']
-
-    def __str__(self):
-        return self.name
-
-    def get_absolute_url(self):
-        return reverse('dcim:powerpanel', args=[self.pk])
-
-    def to_csv(self):
-        return (
-            self.site.name,
-            self.rack_group.name if self.rack_group else None,
-            self.name,
-        )
-
-    def clean(self):
-
-        # RackGroup must belong to assigned Site
-        if self.rack_group and self.rack_group.site != self.site:
-            raise ValidationError("Rack group {} ({}) is in a different site than {}".format(
-                self.rack_group, self.rack_group.site, self.site
-            ))
-
-
-class PowerFeed(ChangeLoggedModel, CableTermination, CustomFieldModel):
-    """
-    An electrical circuit delivered from a PowerPanel.
-    """
-    power_panel = models.ForeignKey(
-        to='PowerPanel',
-        on_delete=models.PROTECT,
-        related_name='powerfeeds'
-    )
-    rack = models.ForeignKey(
-        to='Rack',
-        on_delete=models.PROTECT,
-        blank=True,
-        null=True
-    )
-    connected_endpoint = models.OneToOneField(
-        to='dcim.PowerPort',
-        on_delete=models.SET_NULL,
-        related_name='+',
-        blank=True,
-        null=True
-    )
-    connection_status = models.NullBooleanField(
-        choices=CONNECTION_STATUS_CHOICES,
-        blank=True
-    )
-    name = models.CharField(
-        max_length=50
-    )
-    status = models.PositiveSmallIntegerField(
-        choices=POWERFEED_STATUS_CHOICES,
-        default=POWERFEED_STATUS_ACTIVE
-    )
-    type = models.PositiveSmallIntegerField(
-        choices=POWERFEED_TYPE_CHOICES,
-        default=POWERFEED_TYPE_PRIMARY
-    )
-    supply = models.PositiveSmallIntegerField(
-        choices=POWERFEED_SUPPLY_CHOICES,
-        default=POWERFEED_SUPPLY_AC
-    )
-    phase = models.PositiveSmallIntegerField(
-        choices=POWERFEED_PHASE_CHOICES,
-        default=POWERFEED_PHASE_SINGLE
-    )
-    voltage = models.PositiveSmallIntegerField(
-        validators=[MinValueValidator(1)],
-        default=120
-    )
-    amperage = models.PositiveSmallIntegerField(
-        validators=[MinValueValidator(1)],
-        default=20
-    )
-    max_utilization = models.PositiveSmallIntegerField(
-        validators=[MinValueValidator(1), MaxValueValidator(100)],
-        default=80,
-        help_text="Maximum permissible draw (percentage)"
-    )
-    available_power = models.PositiveSmallIntegerField(
-        default=0,
-        editable=False
-    )
-    comments = models.TextField(
-        blank=True
-    )
-    custom_field_values = GenericRelation(
-        to='extras.CustomFieldValue',
-        content_type_field='obj_type',
-        object_id_field='obj_id'
-    )
-
-    tags = TaggableManager(through=TaggedItem)
-
-    csv_headers = [
-        'site', 'panel_name', 'rack_group', 'rack_name', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
-        'amperage', 'max_utilization', 'comments',
-    ]
-
-    class Meta:
-        ordering = ['power_panel', 'name']
-        unique_together = ['power_panel', 'name']
-
-    def __str__(self):
-        return self.name
-
-    def get_absolute_url(self):
-        return reverse('dcim:powerfeed', args=[self.pk])
-
-    def to_csv(self):
-        return (
-            self.power_panel.site.name,
-            self.power_panel.name,
-            self.rack.group.name if self.rack and self.rack.group else None,
-            self.rack.name if self.rack else None,
-            self.name,
-            self.get_status_display(),
-            self.get_type_display(),
-            self.get_supply_display(),
-            self.get_phase_display(),
-            self.voltage,
-            self.amperage,
-            self.max_utilization,
-            self.comments,
-        )
-
-    def clean(self):
-
-        # Rack must belong to same Site as PowerPanel
-        if self.rack and self.rack.site != self.power_panel.site:
-            raise ValidationError("Rack {} ({}) and power panel {} ({}) are in different sites".format(
-                self.rack, self.rack.site, self.power_panel, self.power_panel.site
-            ))
-
-    def save(self, *args, **kwargs):
-
-        # Cache the available_power property on the instance
-        kva = self.voltage * self.amperage * (self.max_utilization / 100)
-        if self.phase == POWERFEED_PHASE_3PHASE:
-            self.available_power = round(kva * 1.732)
-        else:
-            self.available_power = round(kva)
-
-        super().save(*args, **kwargs)
-
-    def get_type_class(self):
-        return STATUS_CLASSES[self.type]
-
-    def get_status_class(self):
-        return STATUS_CLASSES[self.status]