Skip to content

Commit c10e282

Browse files
committed
Add some design work on making the aggregating endpoint slice functionality the same as the filters - not sure it works as FilterSets don't always allow multiple values, see #HEA-659
1 parent 0623ab3 commit c10e282

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

apps/baseline/serializers.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,43 @@ class Meta:
15421542
"product": "livelihood_strategies__product__cpc__istartswith",
15431543
# this parameter must be set to one of values (not labels) from LivelihoodStrategyType, eg, MilkProduction
15441544
"strategy_type": "livelihood_strategies__strategy_type__iexact",
1545-
# TODO: Support filter expressions on the right here, so we can slice on, for example, a
1545+
# TODO: Integrate the slice functionality with FilterSets. The most natural way to specify a slice would
1546+
# be to use the same terms as for the global filters from the FilterSet, prefixed with `slice_`.
1547+
# Internally, filterset.filter_queryset(self, queryset) runs
1548+
# for name, value in self.form.cleaned_data.items():
1549+
# queryset = self.filters[name].filter(queryset, value)
1550+
# Base Filter.filter runs:
1551+
# lookup = "%s__%s" % (self.field_name, self.lookup_expr)
1552+
# qs = self.get_method(qs)(**{lookup: value})
1553+
# get_method: return qs.exclude if self.exclude else qs.filter
1554+
# We override .filter and don't use get_method, eg, MultiFieldFilter. This'd need fixing.
1555+
# filter.filter then returns Q(**{lookup: value})
1556+
# Solution:
1557+
# Add method FilterSet.generate_q_filter:
1558+
# q = Q()
1559+
# q.filter = lambda (self, **kwargs): self & Q(**kwargs) # or put in class QImplementsQuerySet
1560+
# q.exclude = lambda (self, **kwargs): self & ~Q(**kwargs)
1561+
# q.distinct = lambda (self): self
1562+
# for name, value in self.form.cleaned_data.items():
1563+
# filter = self.filters[name]
1564+
# q &= filter.filter(q, value)
1565+
# # eg, filter.filter repeatedly calls q.filter(field__lookupt=value) or q.filter(another_q)
1566+
# # we iteratively compose a Q instance.
1567+
# # may also call q.distinct() but aggregating endpoint is implicitly distinct
1568+
# delattr(q, "filter")
1569+
# delattr(q, "exclude")
1570+
# delattr(q, "distinct")
1571+
# return q
1572+
# Problem:
1573+
# Slices need multiple values (eg, slice_product=X,slice_product=Y, but FilterSets don't always support them.
1574+
#
1575+
#
1576+
#
1577+
# queryset = self.filters[name].filter(queryset, value)
1578+
#
1579+
#
1580+
#
1581+
# Support filter expressions on the right here, so we can slice on, for example, a
15461582
# WealthGroupCharacteristicValue where WealthGroupCharacteristic is some hard-coded value,
15471583
# eg, the slice on WGCV where WGC=PhoneOwnership, or on WGCV > 3 where WGC=HouseholdSize, eg:
15481584
# {"phone_ownership": lambda val: Q(wgcv__path=val, wgc__path__code="PhoneOwnership")}

0 commit comments

Comments
 (0)