wcs: add operators (#70125)
This commit is contained in:
parent
a08f263abd
commit
270e0b51dc
|
@ -90,31 +90,60 @@ class LazyCardDefObjectsManager:
|
||||||
value = ''
|
value = ''
|
||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
value = str(value).lower()
|
value = str(value).lower()
|
||||||
|
op = getattr(self, 'pending_op', 'eq')
|
||||||
|
if self.pending_attr in ['internal_id', 'number', 'user', 'status']:
|
||||||
|
return getattr(self, 'filter_by_%s' % self.pending_attr)(value, op)
|
||||||
qs._filters['filter-%s' % self.pending_attr] = value
|
qs._filters['filter-%s' % self.pending_attr] = value
|
||||||
|
qs._filters['filter-%s-operator' % self.pending_attr] = op
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def filter_by_internal_id(self, internal_id):
|
def apply_op(self, op):
|
||||||
|
self.pending_op = op
|
||||||
|
return self
|
||||||
|
|
||||||
|
def apply_eq(self):
|
||||||
|
return self.apply_op('eq')
|
||||||
|
|
||||||
|
def apply_ne(self):
|
||||||
|
return self.apply_op('ne')
|
||||||
|
|
||||||
|
def apply_lt(self):
|
||||||
|
return self.apply_op('lt')
|
||||||
|
|
||||||
|
def apply_lte(self):
|
||||||
|
return self.apply_op('lte')
|
||||||
|
|
||||||
|
def apply_gt(self):
|
||||||
|
return self.apply_op('gt')
|
||||||
|
|
||||||
|
def apply_gte(self):
|
||||||
|
return self.apply_op('gte')
|
||||||
|
|
||||||
|
def filter_by_internal_id(self, internal_id, op='eq'):
|
||||||
qs = self._clone()
|
qs = self._clone()
|
||||||
if internal_id:
|
if internal_id:
|
||||||
qs._filters['filter-internal-id'] = internal_id
|
qs._filters['filter-internal-id'] = internal_id
|
||||||
|
qs._filters['filter-internal-id-operator'] = op
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def filter_by_number(self, number):
|
def filter_by_number(self, number, op='eq'):
|
||||||
qs = self._clone()
|
qs = self._clone()
|
||||||
if number:
|
if number:
|
||||||
qs._filters['filter-number'] = number
|
qs._filters['filter-number'] = number
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def filter_by_user(self, user):
|
def filter_by_user(self, user, op='eq'):
|
||||||
qs = self._clone()
|
qs = self._clone()
|
||||||
if user and user.is_authenticated and user.get_name_id():
|
if user and user.is_authenticated and user.get_name_id():
|
||||||
qs._filters['filter-user-uuid'] = user.get_name_id()
|
qs._filters['filter-user-uuid'] = user.get_name_id()
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def filter_by_status(self, status):
|
def filter_by_status(self, status, op='eq'):
|
||||||
qs = self._clone()
|
qs = self._clone()
|
||||||
if status:
|
if status:
|
||||||
qs._filters['filter'] = status
|
qs._filters['filter'] = status
|
||||||
|
if op in ['eq', 'ne']:
|
||||||
|
qs._filters['filter-operator'] = op
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def _get_results_from_wcs(self):
|
def _get_results_from_wcs(self):
|
||||||
|
|
|
@ -74,6 +74,36 @@ def filter_by_status(queryset, status):
|
||||||
return queryset.filter_by_status(status)
|
return queryset.filter_by_status(status)
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='equal')
|
||||||
|
def eq(queryset):
|
||||||
|
return queryset.apply_eq()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='not_equal')
|
||||||
|
def ne(queryset):
|
||||||
|
return queryset.apply_ne()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='less_than')
|
||||||
|
def lt(queryset):
|
||||||
|
return queryset.apply_lt()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='less_than_or_equal')
|
||||||
|
def lte(queryset):
|
||||||
|
return queryset.apply_lte()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='greater_than')
|
||||||
|
def gt(queryset):
|
||||||
|
return queryset.apply_gt()
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='greater_than_or_equal')
|
||||||
|
def gte(queryset):
|
||||||
|
return queryset.apply_gte()
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def order_by(queryset, attribute):
|
def order_by(queryset, attribute):
|
||||||
return queryset.order_by(attribute)
|
return queryset.order_by(attribute)
|
||||||
|
|
|
@ -236,6 +236,16 @@ def test_count(mock_send, context, nocache):
|
||||||
assert t.render(context) == "2"
|
assert t.render(context) == "2"
|
||||||
|
|
||||||
|
|
||||||
|
OPERATORS = [
|
||||||
|
('equal', 'eq'),
|
||||||
|
('not_equal', 'ne'),
|
||||||
|
('less_than', 'lt'),
|
||||||
|
('less_than_or_equal', 'lte'),
|
||||||
|
('greater_than', 'gt'),
|
||||||
|
('greater_than_or_equal', 'gte'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
def test_filter(mock_send, context, nocache):
|
def test_filter(mock_send, context, nocache):
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|list }}')
|
t = Template('{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|list }}')
|
||||||
|
@ -266,6 +276,13 @@ def test_filter(mock_send, context, nocache):
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-foo=&' in mock_send.call_args_list[0][0][0].url
|
assert 'filter-foo=&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
for filter_op, api_op in OPERATORS:
|
||||||
|
mock_send.reset_mock()
|
||||||
|
t = Template('{{ cards|objects:"foo"|filter_by:"foo"|%s|filter_value:"bar"|list }}' % filter_op)
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter-foo=bar&' 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.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
def test_filter_by_internal_id(mock_send, context, nocache):
|
def test_filter_by_internal_id(mock_send, context, nocache):
|
||||||
|
@ -273,20 +290,30 @@ def test_filter_by_internal_id(mock_send, context, nocache):
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
for tpl in ['filter_by_internal_id', 'filter_by:"internal_id"|filter_value']:
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_internal_id:None|list }}')
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t = Template('{{ cards|objects:"foo"|%s:None|list }}' % tpl)
|
||||||
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
t.render(context)
|
||||||
|
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_internal_id:""|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:""|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-internal-id' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_internal_id:"42"|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:"42"|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-internal-id=42&' in mock_send.call_args_list[0][0][0].url
|
assert 'filter-internal-id=42&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
for filter_op, api_op in OPERATORS:
|
||||||
|
mock_send.reset_mock()
|
||||||
|
t = Template(
|
||||||
|
'{{ cards|objects:"foo"|filter_by:"internal_id"|%s|filter_value:"42"|list }}' % filter_op
|
||||||
|
)
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter-internal-id=42&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
assert 'filter-internal-id-operator=%s&' % api_op in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
|
@ -295,42 +322,64 @@ def test_filter_by_number(mock_send, context, nocache):
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
for tpl in ['filter_by_number', 'filter_by:"number"|filter_value']:
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_number:None|list }}')
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t = Template('{{ cards|objects:"foo"|%s:None|list }}' % tpl)
|
||||||
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
t.render(context)
|
||||||
|
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_number:""|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:""|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-number' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_number:"42-35"|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:"42-35"|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-number=42-35&' in mock_send.call_args_list[0][0][0].url
|
assert 'filter-number=42-35&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
for filter_op, api_op in OPERATORS:
|
||||||
|
mock_send.reset_mock()
|
||||||
|
t = Template('{{ cards|objects:"foo"|filter_by:"number"|%s|filter_value:"42-35"|list }}' % filter_op)
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter-number=42-35&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
# not for this filter
|
||||||
|
assert 'filter-number-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
def test_filter_by_user(mock_send, context, nocache):
|
def test_filter_by_user(mock_send, context, nocache):
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_user:request.user|list }}')
|
for tpl in ['filter_by_user', 'filter_by:"user"|filter_value']:
|
||||||
t.render(context)
|
t = Template('{{ cards|objects:"foo"|%s:request.user|list }}' % tpl)
|
||||||
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
mock_send.reset_mock()
|
||||||
|
context['request'].user = None
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
context['request'].user = MockAnonymousUser()
|
context['request'].user = MockAnonymousUser()
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
context['request'].user = MockUser()
|
context['request'].user = MockUser()
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter-user-uuid' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
context['request'].user = MockUserWithNameId()
|
context['request'].user = MockUserWithNameId()
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter-user-uuid=xyz&' in mock_send.call_args_list[0][0][0].url
|
assert 'filter-user-uuid=xyz&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
for filter_op, api_op in OPERATORS:
|
||||||
|
mock_send.reset_mock()
|
||||||
|
t = Template(
|
||||||
|
'{{ cards|objects:"foo"|filter_by:"user"|%s|filter_value:request.user|list }}' % filter_op
|
||||||
|
)
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter-user-uuid=xyz&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
# not for this filter
|
||||||
|
assert 'filter-user-uuid-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
|
@ -338,21 +387,36 @@ def test_filter_by_status(mock_send, context, nocache):
|
||||||
t = Template('{{ cards|objects:"foo"|list }}')
|
t = Template('{{ cards|objects:"foo"|list }}')
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
assert 'filter-operator=eq&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
for tpl in ['filter_by_status', 'filter_by:"status"|filter_value']:
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_status:None|list }}')
|
mock_send.reset_mock()
|
||||||
t.render(context)
|
t = Template('{{ cards|objects:"foo"|%s:None|list }}' % tpl)
|
||||||
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
t.render(context)
|
||||||
|
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
assert 'filter-operator=eq&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_status:""|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:""|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
assert 'filter=&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
assert 'filter-operator=eq&' not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
mock_send.reset_mock()
|
mock_send.reset_mock()
|
||||||
t = Template('{{ cards|objects:"foo"|filter_by_status:"foobar"|list }}')
|
t = Template('{{ cards|objects:"foo"|%s:"foobar"|list }}' % tpl)
|
||||||
t.render(context)
|
t.render(context)
|
||||||
assert 'filter=foobar&' in mock_send.call_args_list[0][0][0].url
|
assert 'filter=foobar&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
assert 'filter-operator=eq&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
for filter_op, api_op in OPERATORS:
|
||||||
|
mock_send.reset_mock()
|
||||||
|
t = Template('{{ cards|objects:"foo"|filter_by:"status"|%s|filter_value:"foobar"|list }}' % filter_op)
|
||||||
|
t.render(context)
|
||||||
|
assert 'filter=foobar&' in mock_send.call_args_list[0][0][0].url
|
||||||
|
if api_op in ['eq', 'ne']:
|
||||||
|
assert 'filter-operator=%s&' % api_op in mock_send.call_args_list[0][0][0].url
|
||||||
|
else:
|
||||||
|
assert 'filter-operator=%s&' % api_op not in mock_send.call_args_list[0][0][0].url
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
@mock.patch('requests.Session.send', side_effect=mocked_requests_send)
|
||||||
|
|
Loading…
Reference in New Issue