wcs: add filter_by and filter_value filters (#49406)

This commit is contained in:
Lauréline Guérin 2020-12-15 15:42:29 +01:00
parent d1f886b46d
commit 1ec70f4b16
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 61 additions and 1 deletions

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.utils.http import urlencode
from requests.exceptions import RequestException
from combo.apps.wcs.utils import get_wcs_services
@ -32,10 +33,11 @@ def get_default_wcs_service_key():
class LazyCardDefObjectsManager(object):
def __init__(self, service_key, card_id, user=Ellipsis):
def __init__(self, service_key, card_id, filters=None, user=Ellipsis):
self._service_key = service_key
self._card_id = card_id
self._filters = filters or {}
self._user = user
self._cached_resultset = None
@ -44,6 +46,7 @@ class LazyCardDefObjectsManager(object):
return LazyCardDefObjectsManager(
service_key=self._service_key,
card_id=self._card_id,
filters=self._filters,
user=self._user)
def access_control(self, user):
@ -55,12 +58,30 @@ class LazyCardDefObjectsManager(object):
def count(self):
return len(self)
def filter_by(self, attribute):
qs = self._clone()
qs.pending_attr = attribute
return qs
def apply_filter_value(self, value):
assert self.pending_attr
qs = self._clone()
if value is None:
value = ''
if isinstance(value, bool):
value = str(value).lower()
qs._filters['filter-%s' % self.pending_attr] = value
return qs
def _get_results_from_wcs(self):
service = get_wcs_services().get(self._service_key)
if not service:
return []
api_url = 'api/cards/%s/list' % self._card_id
if self._filters:
query = urlencode(self._filters)
api_url += '?%s' % query
without_user = self._user is Ellipsis # not set
try:
response = requests.get(

View File

@ -33,3 +33,13 @@ def access_control(queryset, user):
@register.filter
def count(queryset):
return queryset.count
@register.filter
def filter_by(queryset, attribute):
return queryset.filter_by(attribute)
@register.filter
def filter_value(queryset, value):
return queryset.apply_filter_value(value)

View File

@ -193,3 +193,32 @@ def test_access_control(mock_send, context, nocache):
def test_count(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|count }}')
assert t.render(context) == "2"
@mock.patch('combo.apps.wcs.models.requests.send', side_effect=mocked_requests_send)
def test_filter(mock_send, context, nocache):
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|list }}')
t.render(context)
assert 'filter-foo=bar&' in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:"bar"|filter_by:"foo2"|filter_value:"bar2"|list }}')
t.render(context)
assert 'filter-foo=bar&' in mock_send.call_args_list[0][0][0].url
assert 'filter-foo2=bar2&' in mock_send.call_args_list[0][0][0].url
# check boolean
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:True|list }}')
t.render(context)
assert 'filter-foo=true&' in mock_send.call_args_list[0][0][0].url
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:False|list }}')
t.render(context)
assert 'filter-foo=false&' in mock_send.call_args_list[0][0][0].url
# check None
mock_send.reset_mock()
t = Template('{% load wcs %}{{ cards|objects:"foo"|filter_by:"foo"|filter_value:None|list }}')
t.render(context)
assert 'filter-foo=&' in mock_send.call_args_list[0][0][0].url