From 44b842592ae803b4cd6d1bbda6d11170035f4f9a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 6 Oct 2020 16:58:11 -0400 Subject: [PATCH] Restore total length count on trace view --- docs/release-notes/version-2.10.md | 8 ++++++-- netbox/dcim/models/devices.py | 14 ++++++++++++-- netbox/dcim/utils.py | 13 +++++++++++-- netbox/dcim/views.py | 6 +----- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 253ed0612..fa3f3aea8 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -71,7 +71,9 @@ All end-to-end cable paths are now cached using the new CablePath model. This al * dcim.ConsoleServerPort: * Replaced `connection_status` with `connected_endpoint_reachable` (boolean) * Added `cable_peer` and `cable_peer_type` -* dcim.FrontPort: Added `cable_peer` and `cable_peer_type` +* dcim.FrontPort: + * Removed the `/trace/` endpoint + * Added `cable_peer` and `cable_peer_type` * dcim.Interface: * Replaced `connection_status` with `connected_endpoint_reachable` (boolean) * Added `cable_peer` and `cable_peer_type` @@ -85,7 +87,9 @@ All end-to-end cable paths are now cached using the new CablePath model. This al * Replaced `connection_status` with `connected_endpoint_reachable` (boolean) * Added `cable_peer` and `cable_peer_type` * dcim.RackReservation: Added `custom_fields` -* dcim.RearPort: Added `cable_peer` and `cable_peer_type` +* dcim.RearPort: + * Removed the `/trace/` endpoint + * Added `cable_peer` and `cable_peer_type` * dcim.VirtualChassis: Added `custom_fields` * extras.ExportTemplate: The `template_language` field has been removed * extras.Graph: This API endpoint has been removed (see #4349) diff --git a/netbox/dcim/models/devices.py b/netbox/dcim/models/devices.py index e4ea551b9..b44146b99 100644 --- a/netbox/dcim/models/devices.py +++ b/netbox/dcim/models/devices.py @@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models -from django.db.models import F, ProtectedError +from django.db.models import F, ProtectedError, Sum from django.urls import reverse from django.utils.safestring import mark_safe from taggit.managers import TaggableManager @@ -15,7 +15,7 @@ from taggit.managers import TaggableManager from dcim.choices import * from dcim.constants import * from dcim.fields import PathField -from dcim.utils import path_node_to_object +from dcim.utils import decompile_path_node, path_node_to_object from extras.models import ChangeLoggedModel, ConfigContextModel, CustomFieldModel, TaggedItem from extras.utils import extras_features from utilities.choices import ColorChoices @@ -1228,6 +1228,16 @@ class CablePath(models.Model): model = self.origin._meta.model model.objects.filter(pk=self.origin.pk).update(_path=self.pk) + def get_total_length(self): + """ + Return the sum of the length of each cable in the path. + """ + cable_ids = [ + # Starting from the first element, every third element in the path should be a Cable + decompile_path_node(self.path[i])[1] for i in range(0, len(self.path), 3) + ] + return Cable.objects.filter(id__in=cable_ids).aggregate(total=Sum('_abs_length'))['total'] + # # Virtual chassis diff --git a/netbox/dcim/utils.py b/netbox/dcim/utils.py index ccc849aa5..52b0a4232 100644 --- a/netbox/dcim/utils.py +++ b/netbox/dcim/utils.py @@ -4,20 +4,29 @@ from .choices import CableStatusChoices from .exceptions import CableTraceSplit +def compile_path_node(ct_id, object_id): + return f'{ct_id}:{object_id}' + + +def decompile_path_node(repr): + ct_id, object_id = repr.split(':') + return int(ct_id), int(object_id) + + def object_to_path_node(obj): """ Return a representation of an object suitable for inclusion in a CablePath path. Node representation is in the form :. """ ct = ContentType.objects.get_for_model(obj) - return f'{ct.pk}:{obj.pk}' + return compile_path_node(ct.pk, obj.pk) def path_node_to_object(repr): """ Given a path node representation, return the corresponding object. """ - ct_id, object_id = repr.split(':') + ct_id, object_id = decompile_path_node(repr) model_class = ContentType.objects.get(pk=ct_id).model_class() return model_class.objects.get(pk=int(object_id)) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 696b7f356..ff4ec1ef6 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1984,15 +1984,11 @@ class PathTraceView(ObjectView): else: path = related_paths.first() - # total_length = sum( - # [entry[1]._abs_length for entry in path if entry[1] and entry[1]._abs_length] - # ) - return render(request, 'dcim/cable_trace.html', { 'obj': obj, 'path': path, 'related_paths': related_paths, - # 'total_length': total_length, + 'total_length': path.get_total_length(), })