diff --git a/geonode/base/api/tests.py b/geonode/base/api/tests.py index d1bd19f645a..dcf6225f3d1 100644 --- a/geonode/base/api/tests.py +++ b/geonode/base/api/tests.py @@ -1672,6 +1672,80 @@ def test_keywords_list(self): self.assertEqual(response.status_code, 200) self.assertEqual(response.data['total'], 0) + # Testing Hierarchical Keywords tree + try: + HierarchicalKeyword.objects.filter(slug__in=['a', 'a1', 'a2', 'b', 'b1']).delete() + HierarchicalKeyword.add_root(name='a') + HierarchicalKeyword.add_root(name='b') + a = HierarchicalKeyword.objects.get(slug='a') + b = HierarchicalKeyword.objects.get(slug='b') + a.add_child(name='a1') + a.add_child(name='a2') + b.add_child(name='b1') + resources = ResourceBase.objects.filter(owner__username='bobby') + res1 = resources.first() + res2 = resources.last() + self.assertNotEqual(res1, res2) + res1.keywords.add(HierarchicalKeyword.objects.get(slug='a1')) + res1.keywords.add(HierarchicalKeyword.objects.get(slug='a2')) + res2.keywords.add(HierarchicalKeyword.objects.get(slug='b1')) + resource_keywords = HierarchicalKeyword.resource_keywords_tree(bobby) + logger.error(resource_keywords) + + """ + Final api outcome will be something like + [ + { + 'id': 116, + 'text': 'a', + 'href': 'a', + 'tags': [], + 'nodes': [ + { + 'id': 118, + 'text': 'a1', + 'href': 'a1', + 'tags': [1] + }, + { + 'id': 119, + 'text': 'a2', + 'href': 'a2', + 'tags': [1] + } + ] + }, + { + 'id': 117, + 'text': 'b', + 'href': 'b', + 'tags': [], + 'nodes': [ + { + 'id': 120, + 'text': 'b1', + 'href': 'b1', + 'tags': [1] + } + ] + }, + ... + ] + """ + url = reverse('keywords-list') + # Authenticated user + self.assertTrue(self.client.login(username='bobby', password='bob')) + response = self.client.get(url, format='json') + self.assertEqual(response.status_code, 200) + for _kw in response.data["keywords"]: + if _kw.get('href') in ['a', 'b']: + self.assertListEqual(_kw.get('tags'), [], _kw.get('tags')) + self.assertEqual(len(_kw.get('nodes')), 2) + for _kw_child in _kw.get('nodes'): + self.assertEqual(_kw_child.get('tags')[0], 1) + finally: + HierarchicalKeyword.objects.filter(slug__in=['a', 'a1', 'a2', 'b', 'b1']).delete() + def test_tkeywords_list(self): """ Ensure we can access the list of thasaurus keywords. diff --git a/geonode/base/api/views.py b/geonode/base/api/views.py index 928f4086fba..bf90f4c9702 100644 --- a/geonode/base/api/views.py +++ b/geonode/base/api/views.py @@ -228,7 +228,15 @@ class HierarchicalKeywordViewSet(WithDynamicViewSetMixin, ListModelMixin, Retrie def get_queryset(self): resource_keywords = HierarchicalKeyword.resource_keywords_tree(self.request.user) - slugs = [obj.get('href') for obj in resource_keywords] + + def _get_kw_hrefs(keywords, slugs: list = []): + for obj in keywords: + if obj.get('tags', []): + slugs.append(obj.get('href')) + _get_kw_hrefs(obj.get('nodes', []), slugs) + return slugs + + slugs = _get_kw_hrefs(resource_keywords) return HierarchicalKeyword.objects.filter(slug__in=slugs) permission_classes = [AllowAny, ] diff --git a/geonode/base/models.py b/geonode/base/models.py index 44b9336defb..681da55645a 100644 --- a/geonode/base/models.py +++ b/geonode/base/models.py @@ -421,6 +421,7 @@ def _keywords_tree_of_a_child(cls, child, tree, newobj): node = node["nodes"][-1] else: node = item_found + node["nodes"] = getattr(node, "nodes", []) # All leaves appended but a child which is not a leaf may not be added # again, as a leaf, but only its tag count be updated