Skip to content

Commit a667ac8

Browse files
committed
Update LivelihoodZoneBaselineFacetedSearchView to support livelihood_strategy_types see HEA-947
1 parent d3cf776 commit a667ac8

1 file changed

Lines changed: 61 additions & 8 deletions

File tree

apps/baseline/viewsets.py

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717

1818
from common.fields import translation_fields
1919
from common.filters import DefaultingDateFilter, MultiFieldFilter, UpperCaseFilter
20+
from common.models import ClassifiedProduct
2021
from common.utils import make_condition_funcs
2122
from common.viewsets import AggregatingViewSet, BaseModelViewSet
22-
from metadata.models import WealthGroupCategory
23+
from metadata.models import LivelihoodStrategyType, WealthGroupCategory
2324

2425
from .models import (
2526
BaselineLivelihoodActivity,
@@ -212,6 +213,7 @@ class Meta:
212213
wealth_characteristic = CharFilter(
213214
method="filter_by_wealth_characteristic", label="Filter by Wealth Characteristic"
214215
)
216+
strategy_type = CharFilter(method="filter_by_strategy_type", label="Filter by Strategy Type")
215217
as_of_date = DefaultingDateFilter(
216218
label="As of Date",
217219
help_text="Filter baselines valid as of this date (YYYY-MM-DD format or special values like 'today').",
@@ -257,6 +259,13 @@ def filter_by_wealth_characteristic(self, queryset, name, value):
257259

258260
return queryset.filter(id__in=Subquery(matching_baselines))
259261

262+
def filter_by_strategy_type(self, queryset, name, value):
263+
"""
264+
Filter the baseline by matching livelihood strategy type
265+
"""
266+
matching_baselines = LivelihoodStrategy.objects.filter(strategy_type=value).values("livelihood_zone_baseline")
267+
return queryset.filter(id__in=Subquery(matching_baselines))
268+
260269

261270
class LivelihoodZoneBaselineViewSet(BaseModelViewSet):
262271
"""
@@ -2088,6 +2097,16 @@ class LivelihoodZoneBaselineFacetedSearchView(APIView):
20882097
renderer_classes = [JSONRenderer]
20892098
permission_classes = [AllowAny]
20902099

2100+
def _search_products(self, search_term):
2101+
# Search products using icontains for broader matching than the default iexact search.
2102+
q_object = Q()
2103+
for field in [*translation_fields("description"), *translation_fields("common_name")]:
2104+
q_object |= Q(**{f"{field}__icontains": search_term})
2105+
q_object |= Q(cpc__iexact=search_term)
2106+
q_object |= Q(aliases__contains=[search_term.lower()])
2107+
q_object |= Q(scientific_name__icontains=search_term)
2108+
return ClassifiedProduct.objects.filter(q_object).distinct()
2109+
20912110
def get(self, request, format=None):
20922111
"""
20932112
Return a faceted set of matching filters
@@ -2100,13 +2119,14 @@ def get(self, request, format=None):
21002119
for model_entry in MODELS_TO_SEARCH:
21012120
app_name = model_entry["app_name"]
21022121
model_name = model_entry["model_name"]
2103-
filter, filter_label, filter_category = (
2104-
model_entry["filter"]["key"],
2105-
model_entry["filter"]["label"],
2106-
model_entry["filter"]["category"],
2107-
)
2122+
filter_key = model_entry["filter"]["key"]
2123+
filter_label = model_entry["filter"]["label"]
2124+
filter_category = model_entry["filter"]["category"]
21082125
ModelClass = apps.get_model(app_name, model_name)
2109-
search_per_model = ModelClass.objects.search(search_term)
2126+
if model_name == "ClassifiedProduct":
2127+
search_per_model = self._search_products(search_term)
2128+
else:
2129+
search_per_model = ModelClass.objects.search(search_term)
21102130
results[filter_category] = []
21112131
# for activating language
21122132
with override(language):
@@ -2145,12 +2165,45 @@ def get(self, request, format=None):
21452165
if unique_zones > 0:
21462166
results[filter_category].append(
21472167
{
2148-
"filter": filter,
2168+
"filter": filter_key,
21492169
"filter_label": filter_label,
21502170
"value_label": value_label,
21512171
"value": value,
21522172
"count": unique_zones,
21532173
}
21542174
)
21552175

2176+
# Search livelihood strategy types (not a model query)
2177+
results["livelihood_strategy_types"] = []
2178+
search_lower = search_term.lower()
2179+
# Get English labels outside language override for matching
2180+
english_labels = {}
2181+
with override("en"):
2182+
for strategy_type in LivelihoodStrategyType:
2183+
english_labels[strategy_type.value] = str(strategy_type.label).lower()
2184+
with override(language):
2185+
for strategy_type in LivelihoodStrategyType:
2186+
translated_label = str(strategy_type.label)
2187+
if (
2188+
search_lower in strategy_type.value.lower()
2189+
or search_lower in english_labels[strategy_type.value]
2190+
or search_lower in translated_label.lower()
2191+
):
2192+
unique_zones = (
2193+
LivelihoodStrategy.objects.filter(strategy_type=strategy_type.value)
2194+
.values("livelihood_zone_baseline")
2195+
.distinct()
2196+
.count()
2197+
)
2198+
if unique_zones > 0:
2199+
results["livelihood_strategy_types"].append(
2200+
{
2201+
"filter": "strategy_type",
2202+
"filter_label": "Livelihood Strategy Type",
2203+
"value_label": translated_label,
2204+
"value": strategy_type.value,
2205+
"count": unique_zones,
2206+
}
2207+
)
2208+
21562209
return Response(results)

0 commit comments

Comments
 (0)