From ead2f1828d5732b3d858d0cc9173d02405ae1071 Mon Sep 17 00:00:00 2001
From: Kenzo-Hugo Hillion <kenzo-hugo.hillion1@pasteur.fr>
Date: Mon, 4 Nov 2019 18:06:28 +0100
Subject: [PATCH] Optimise to not have to build hierarchy everytime

---
 .../metagenedb/api/catalog/views/taxonomy.py  |  2 +-
 .../apps/catalog/models/taxonomy.py           | 26 +++++++++++++++++--
 .../apps/catalog/models/test_taxonomy.py      |  5 +++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/backend/metagenedb/api/catalog/views/taxonomy.py b/backend/metagenedb/api/catalog/views/taxonomy.py
index 9b6f92e..2f9b484 100644
--- a/backend/metagenedb/api/catalog/views/taxonomy.py
+++ b/backend/metagenedb/api/catalog/views/taxonomy.py
@@ -15,6 +15,6 @@ class TaxonomyViewSet(BulkViewSet):
 
     def retrieve(self, request, *args, **kwargs):
         instance = self.get_object()
-        instance.build_parental_hierarchy()
+        hierarchy = instance.parental_hierarchy  # noqa
         serializer = self.get_serializer(instance)
         return Response(serializer.data)
diff --git a/backend/metagenedb/apps/catalog/models/taxonomy.py b/backend/metagenedb/apps/catalog/models/taxonomy.py
index bc3498d..13c5c01 100644
--- a/backend/metagenedb/apps/catalog/models/taxonomy.py
+++ b/backend/metagenedb/apps/catalog/models/taxonomy.py
@@ -97,11 +97,33 @@ class Taxonomy(models.Model):
     def __str__(self):
         return f"{self.name}"
 
-    def build_parental_hierarchy(self):
+    @property
+    def parental_hierarchy(self):
+        if self.kingdom is None and self.superkingdom is None:
+            return self._build_parental_hierarchy()
+        return self._dict_parental_hierarchy()
+
+    def _dict_parental_hierarchy(self):
+        """
+        Return parental hierarchy from
+        """
+        ranks = [
+            "superkingdom", "kingdom", "phylum", "class_rank", "order", "family", "genus", "species"
+        ]
+        hierarchy = {}
+        for rank in ranks:
+            if getattr(self, rank, None) is not None:
+                hierarchy[rank] = getattr(self, rank)
+        return hierarchy
+
+    def _build_parental_hierarchy(self):
+        """
+        Build and save parental hierarchy for an entry
+        """
         hierarchy = {}
         if self.name != 'root' and self.parent is not None:
             hierarchy[self.rank] = self
-            hierarchy = {**hierarchy, **self.parent.build_parental_hierarchy()}
+            hierarchy = {**hierarchy, **self.parent.parental_hierarchy}
         for level, value in hierarchy.items():
             setattr(self, level, value)
         self.save()
diff --git a/backend/metagenedb/apps/catalog/models/test_taxonomy.py b/backend/metagenedb/apps/catalog/models/test_taxonomy.py
index a9e8cad..3263bd6 100644
--- a/backend/metagenedb/apps/catalog/models/test_taxonomy.py
+++ b/backend/metagenedb/apps/catalog/models/test_taxonomy.py
@@ -33,6 +33,9 @@ class TestBuildHierarchy(APITestCase):
             'kingdom': self.kingdom
         }
         self.assertNotEqual(getattr(self.phylum, 'kingdom', None), self.kingdom)
-        test_dict = self.phylum.build_parental_hierarchy()
+        test_dict = self.phylum.parental_hierarchy
         self.assertDictEqual(test_dict, expected_dict)
         self.assertEqual(getattr(self.phylum, 'kingdom', None), self.kingdom)
+        # Now try a second time from saved information
+        test_dict = self.phylum.parental_hierarchy
+        self.assertDictEqual(test_dict, expected_dict)
-- 
GitLab