diff --git a/publik_django_templatetags/wcs/context_processors.py b/publik_django_templatetags/wcs/context_processors.py index 8228f3a..16a52d2 100644 --- a/publik_django_templatetags/wcs/context_processors.py +++ b/publik_django_templatetags/wcs/context_processors.py @@ -175,6 +175,23 @@ class LazyCardDefObjectsManager: def apply_gte(self): return self.apply_op('gte') + def apply_in(self): + return self.apply_op('in') + + def apply_not_in(self): + return self.apply_op('not_in') + + def apply_between(self): + return self.apply_op('between') + + def apply_absent(self): + self.apply_op('absent') + return self.apply_filter_value('on') + + def apply_existing(self): + self.apply_op('existing') + return self.apply_filter_value('on') + def filter_by_internal_id(self, internal_id, op='eq'): qs = self._clone() if internal_id: diff --git a/publik_django_templatetags/wcs/templatetags/wcs.py b/publik_django_templatetags/wcs/templatetags/wcs.py index dfd6982..9bda88c 100644 --- a/publik_django_templatetags/wcs/templatetags/wcs.py +++ b/publik_django_templatetags/wcs/templatetags/wcs.py @@ -208,6 +208,46 @@ def gte(queryset): return None +@register.filter(name='in') +def _in(queryset): + try: + return queryset.apply_in() + except AttributeError: + return None + + +@register.filter() +def not_in(queryset): + try: + return queryset.apply_not_in() + except AttributeError: + return None + + +@register.filter() +def between(queryset): + try: + return queryset.apply_between() + except AttributeError: + return None + + +@register.filter() +def absent(queryset): + try: + return queryset.apply_absent() + except AttributeError: + return None + + +@register.filter() +def existing(queryset): + try: + return queryset.apply_existing() + except AttributeError: + return None + + @register.filter def order_by(queryset, attribute): try: diff --git a/tests/test_wcs.py b/tests/test_wcs.py index 9de5c5d..bd7a187 100644 --- a/tests/test_wcs.py +++ b/tests/test_wcs.py @@ -347,6 +347,13 @@ OPERATORS = [ ('less_than_or_equal', 'lte'), ('greater_than', 'gt'), ('greater_than_or_equal', 'gte'), + ('in', 'in'), + ('not_in', 'not_in'), + ('between', 'between'), +] +OPERATORS_WITHOUT_VALUE = [ + ('absent', 'absent'), + ('existing', 'existing'), ] @@ -393,6 +400,18 @@ def test_filter(mock_send, context, nocache): t.render(context) assert mock_send.call_args_list == [] + for filter_op, api_op in OPERATORS_WITHOUT_VALUE: + mock_send.reset_mock() + t = Template('{{ cards|objects:"foo"|filter_by:"foo"|%s|list }}' % filter_op) + t.render(context) + assert 'filter-foo=on&' in mock_send.call_args_list[0][0][0].url + assert 'filter-foo-operator=%s&' % api_op in mock_send.call_args_list[0][0][0].url + + mock_send.reset_mock() + t = Template('{{ foobar|%s }}' % filter_op) + t.render(context) + assert mock_send.call_args_list == [] + mock_send.reset_mock() t = Template('{{ foobar|filter_by:"foo"|list }}') t.render(context)