def get_path(self): """ Return the path as a list of prefetched objects. """ # Compile a list of IDs to prefetch for each type of model in the path to_prefetch = defaultdict(list) for node in self.path: ct_id, object_id = decompile_path_node(node) to_prefetch[ct_id].append(object_id) # Prefetch path objects using one query per model type. Prefetch related devices where appropriate. prefetched = {} for ct_id, object_ids in to_prefetch.items(): model_class = ContentType.objects.get_for_id(ct_id).model_class() queryset = model_class.objects.filter(pk__in=object_ids) if hasattr(model_class, 'device'): queryset = queryset.prefetch_related('device') prefetched[ct_id] = {obj.id: obj for obj in queryset} # Replicate the path using the prefetched objects. path = [] for node in self.path: ct_id, object_id = decompile_path_node(node) path.append(prefetched[ct_id][object_id]) return path
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']
def get_cable_ids(self): """ Return all Cable IDs within the path. """ cable_ct = ContentType.objects.get_for_model(Cable).pk cable_ids = [] for node in self.path: ct, id = decompile_path_node(node) if ct == cable_ct: cable_ids.append(id) return cable_ids
def get_total_length(self): """ Return a tuple containing the sum of the length of each cable in the path and a flag indicating whether the length is definitive. """ 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) ] cables = Cable.objects.filter(id__in=cable_ids, _abs_length__isnull=False) total_length = cables.aggregate(total=Sum('_abs_length'))['total'] is_definitive = len(cables) == len(cable_ids) return total_length, is_definitive