Пример #1
0
    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
Пример #2
0
 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"]