Skip to content

Commit 82fa70f

Browse files
committed
OpenConceptLab/ocl_issues#991 | API get parents of a concept
1 parent b0973e6 commit 82fa70f

5 files changed

Lines changed: 76 additions & 2 deletions

File tree

core/concepts/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,12 @@ def child_concept_queryset(self):
805805
return Concept.objects.filter(uri__in=urls)
806806
return Concept.objects.none()
807807

808+
def parent_concept_queryset(self):
809+
urls = self.parent_concept_urls
810+
if urls:
811+
return Concept.objects.filter(uri__in=urls)
812+
return Concept.objects.none()
813+
808814
@staticmethod
809815
def __format_hierarchy_uris(uris):
810816
return list({drop_version(uri) for uri in uris})

core/concepts/serializers.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,27 @@ class ConceptHierarchySerializer(ModelSerializer):
481481
class Meta:
482482
model = Concept
483483
fields = ('uuid', 'id', 'url', 'children', 'name')
484+
485+
486+
class ConceptChildrenSerializer(ModelSerializer):
487+
uuid = CharField(source='id')
488+
id = EncodedDecodedCharField(source='mnemonic')
489+
url = CharField(source='uri')
490+
children = ListField(source='child_concept_urls')
491+
name = CharField(source='display_name')
492+
493+
class Meta:
494+
model = Concept
495+
fields = ('uuid', 'id', 'url', 'children', 'name')
496+
497+
498+
class ConceptParentsSerializer(ModelSerializer):
499+
uuid = CharField(source='id')
500+
id = EncodedDecodedCharField(source='mnemonic')
501+
url = CharField(source='uri')
502+
parents = ListField(source='parent_concept_urls')
503+
name = CharField(source='display_name')
504+
505+
class Meta:
506+
model = Concept
507+
fields = ('uuid', 'id', 'url', 'parents', 'name')

core/concepts/tests/tests.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,35 @@ def test_child_concept_queryset(self):
951951
list(child_child_concept.child_concept_queryset().values_list('uri', flat=True)), [])
952952
self.assertEqual(child_child_concept.parent_concept_urls, [child_concept.uri])
953953

954+
def test_parent_concept_queryset(self):
955+
parent_concept = ConceptFactory()
956+
self.assertEqual(parent_concept.parent_concept_queryset().count(), 0)
957+
self.assertEqual(parent_concept.parent_concept_urls, [])
958+
959+
child_concept = Concept.persist_new({
960+
**factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c1', 'parent': parent_concept.parent,
961+
'names': [LocalizedTextFactory.build(locale='en', name='English', locale_preferred=True)],
962+
'parent_concept_urls': [parent_concept.uri]
963+
})
964+
self.assertEqual(
965+
list(parent_concept.parent_concept_queryset().values_list('uri', flat=True)), [])
966+
self.assertEqual(
967+
list(child_concept.parent_concept_queryset().values_list('uri', flat=True)), [parent_concept.uri])
968+
self.assertEqual(child_concept.parent_concept_urls, [parent_concept.uri])
969+
970+
child_child_concept = Concept.persist_new({
971+
**factory.build(dict, FACTORY_CLASS=ConceptFactory), 'mnemonic': 'c2', 'parent': parent_concept.parent,
972+
'names': [LocalizedTextFactory.build(locale='en', name='English', locale_preferred=True)],
973+
'parent_concept_urls': [child_concept.uri]
974+
})
975+
self.assertEqual(
976+
list(parent_concept.parent_concept_queryset().values_list('uri', flat=True)), [])
977+
self.assertEqual(
978+
list(child_concept.parent_concept_queryset().values_list('uri', flat=True)), [parent_concept.uri])
979+
self.assertEqual(
980+
list(child_child_concept.parent_concept_queryset().values_list('uri', flat=True)), [child_concept.uri])
981+
self.assertEqual(child_child_concept.parent_concept_urls, [child_concept.uri])
982+
954983

955984
class OpenMRSConceptValidatorTest(OCLTestCase):
956985
def setUp(self):

core/concepts/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
views.ConceptChildrenView.as_view(),
3131
name='concept-children'
3232
),
33+
path(
34+
"<str:concept>/parents/",
35+
views.ConceptParentsView.as_view(),
36+
name='concept-parents'
37+
),
3338
path('<str:concept>/atom/', ConceptFeed()),
3439
path(
3540
"<str:concept>/descriptions/",

core/concepts/views.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
from core.concepts.serializers import (
3232
ConceptDetailSerializer, ConceptListSerializer, ConceptDescriptionSerializer, ConceptNameSerializer,
3333
ConceptVersionDetailSerializer,
34-
ConceptVersionListSerializer, ConceptHierarchySerializer, ConceptSummarySerializer, ConceptMinimalSerializer)
34+
ConceptVersionListSerializer, ConceptSummarySerializer, ConceptMinimalSerializer,
35+
ConceptChildrenSerializer, ConceptParentsSerializer)
3536
from core.mappings.serializers import MappingListSerializer
3637

3738

@@ -279,14 +280,23 @@ def destroy(self, request, *args, **kwargs):
279280

280281

281282
class ConceptChildrenView(ConceptBaseView, ListAPIView):
282-
serializer_class = ConceptHierarchySerializer
283+
serializer_class = ConceptChildrenSerializer
283284

284285
def get_queryset(self):
285286
instance = get_object_or_404(super().get_queryset(), id=F('versioned_object_id'))
286287
self.check_object_permissions(self.request, instance)
287288
return instance.child_concept_queryset()
288289

289290

291+
class ConceptParentsView(ConceptBaseView, ListAPIView):
292+
serializer_class = ConceptParentsSerializer
293+
294+
def get_queryset(self):
295+
instance = get_object_or_404(super().get_queryset(), id=F('versioned_object_id'))
296+
self.check_object_permissions(self.request, instance)
297+
return instance.parent_concept_queryset()
298+
299+
290300
class ConceptReactivateView(ConceptBaseView, UpdateAPIView):
291301
serializer_class = ConceptDetailSerializer
292302

0 commit comments

Comments
 (0)