From 492df5405c2ae2506d5828b89209565397089987 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Tue, 2 Oct 2018 10:39:17 -0400 Subject: [PATCH] cluster API --- src/etools/applications/partners/models.py | 2 +- .../partners/views/interventions_v2.py | 2 +- .../applications/reports/serializers/v2.py | 7 +++ .../applications/reports/tests/test_views.py | 52 ++++++++++++++++++- src/etools/applications/reports/urls_v2.py | 7 ++- src/etools/applications/reports/views/v2.py | 13 +++++ 6 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/etools/applications/partners/models.py b/src/etools/applications/partners/models.py index f3cda17d74..6c8e3f3923 100644 --- a/src/etools/applications/partners/models.py +++ b/src/etools/applications/partners/models.py @@ -1537,7 +1537,7 @@ def frs_qs(self): def maps_qs(self): qs = self.get_queryset().prefetch_related('flat_locations').distinct().annotate( results=StringConcat("result_links__cp_output__name", separator="|", distinct=True), - clusters=StringConcat("result_links__ll_results__applied_indicators__cluster_indicator_title", + clusters=StringConcat("result_links__ll_results__applied_indicators__cluster_name", separator="|", distinct=True), ) return qs diff --git a/src/etools/applications/partners/views/interventions_v2.py b/src/etools/applications/partners/views/interventions_v2.py index 51c9e2683f..42032256a9 100644 --- a/src/etools/applications/partners/views/interventions_v2.py +++ b/src/etools/applications/partners/views/interventions_v2.py @@ -533,7 +533,7 @@ class InterventionListMapView(QueryStringFilterMixin, ListCreateAPIView): ('grants', 'frs__fr_items__grant_number__in'), ('unicef_focal_points', 'unicef_focal_points__in'), ('interventions', 'pk__in'), - ('clusters', 'result_links__ll_results__applied_indicators__cluster_indicator_title__icontains'), + ('clusters', 'result_links__ll_results__applied_indicators__cluster_name__icontains'), ) def get_queryset(self): diff --git a/src/etools/applications/reports/serializers/v2.py b/src/etools/applications/reports/serializers/v2.py index 9186bf6aeb..85b9972a85 100644 --- a/src/etools/applications/reports/serializers/v2.py +++ b/src/etools/applications/reports/serializers/v2.py @@ -193,6 +193,13 @@ class Meta: fields = '__all__' +class ClusterSerializer(serializers.ModelSerializer): + + class Meta: + model = AppliedIndicator + fields = 'cluster_name', + + class LowerResultSimpleCUSerializer(serializers.ModelSerializer): code = serializers.CharField(read_only=True) diff --git a/src/etools/applications/reports/tests/test_views.py b/src/etools/applications/reports/tests/test_views.py index 03b0b1e04c..1538958c65 100644 --- a/src/etools/applications/reports/tests/test_views.py +++ b/src/etools/applications/reports/tests/test_views.py @@ -1,9 +1,8 @@ import datetime from operator import itemgetter -from django.urls import reverse from django.test import SimpleTestCase - +from django.urls import reverse from rest_framework import status from tablib.core import Dataset @@ -861,6 +860,55 @@ def test_csv_flat_export_api(self): self.assertEqual(len(dataset[0]), 31) +class TestClusterListAPIView(BaseTenantTestCase): + @classmethod + def setUpTestData(cls): + cls.unicef_staff = UserFactory(is_staff=True) + cls.intervention = InterventionFactory() + cls.result_link = InterventionResultLinkFactory() + cls.lower_result = LowerResultFactory( + name="LL Name", + result_link=cls.result_link, + ) + cls.indicator = IndicatorBlueprintFactory() + AppliedIndicatorFactory( + context_code="CC321", + indicator=cls.indicator, + lower_result=LowerResultFactory(name="LL Name", result_link=cls.result_link), + cluster_name='ABC', + ) + AppliedIndicatorFactory( + context_code="CC321", + indicator=cls.indicator, + lower_result=LowerResultFactory(name="LL Name", result_link=cls.result_link), + cluster_name='XYZ', + ) + AppliedIndicatorFactory( + context_code="CC321", + indicator=cls.indicator, + lower_result=LowerResultFactory(name="LL Name", result_link=cls.result_link), + cluster_name='XYZ', + ) + AppliedIndicatorFactory( + context_code="CC321", + indicator=cls.indicator, + lower_result=LowerResultFactory(name="LL Name", result_link=cls.result_link), + ) + cls.url = reverse("reports:cluster") + + def test_get(self): + response = self.forced_auth_req( + "get", + self.url, + user=self.unicef_staff, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 2) + clusters = [item['cluster_name'] for item in response.data] + clusters.sort() + self.assertEquals(['ABC', 'XYZ'], clusters) + + class TestSpecialReportingRequirementListCreateView(BaseTenantTestCase): @classmethod def setUpTestData(cls): diff --git a/src/etools/applications/reports/urls_v2.py b/src/etools/applications/reports/urls_v2.py index 9e3b59bfb3..1f6b0c6e81 100644 --- a/src/etools/applications/reports/urls_v2.py +++ b/src/etools/applications/reports/urls_v2.py @@ -1,10 +1,12 @@ -from django.conf.urls import url, include +from django.conf.urls import include, url + from rest_framework import routers from etools.applications.reports.views.v1 import CountryProgrammeListView, CountryProgrammeRetrieveView, SectionViewSet from etools.applications.reports.views.v2 import ( AppliedIndicatorListAPIView, AppliedIndicatorLocationExportView, + ClusterListAPIView, DisaggregationListCreateView, DisaggregationRetrieveUpdateView, LowerResultsDeleteView, @@ -28,6 +30,9 @@ url(r'^applied-indicators/intervention/$', view=AppliedIndicatorLocationExportView.as_view(http_method_names=['get']), name='intervention-applied-indicator'), + url(r'^clusters/$', + view=ClusterListAPIView.as_view(http_method_names=['get']), + name='cluster'), url(r'^lower_results/$', view=LowerResultsListAPIView.as_view(http_method_names=['get']), name='lower-results'), diff --git a/src/etools/applications/reports/views/v2.py b/src/etools/applications/reports/views/v2.py index 263c807766..b79adf01d8 100644 --- a/src/etools/applications/reports/views/v2.py +++ b/src/etools/applications/reports/views/v2.py @@ -46,6 +46,7 @@ from etools.applications.reports.serializers.v1 import IndicatorSerializer from etools.applications.reports.serializers.v2 import ( AppliedIndicatorSerializer, + ClusterSerializer, DisaggregationSerializer, LowerResultSerializer, MinimalOutputListSerializer, @@ -388,6 +389,18 @@ def get_indicators(self, intervention): return qs +class ClusterListAPIView(ListAPIView): + """Returns a list of Clusters""" + model = AppliedIndicator + serializer_class = ClusterSerializer + renderer_classes = ( + JSONRenderer, + CSVRenderer, + CSVFlatRenderer, + ) + queryset = AppliedIndicator.objects.filter(cluster_name__isnull=False).values('cluster_name').distinct() + + class SpecialReportingRequirementListCreateView(ListCreateAPIView): serializer_class = SpecialReportingRequirementSerializer permission_classes = (PartnershipManagerPermission, )