def test_multivaluedict(self): d = MultiValueDict({ 'name': ['Adrian', 'Simon'], 'position': ['Developer'] }) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual(sorted(d.items()), [('name', 'Simon'), ('position', 'Developer')]) self.assertEqual(sorted(d.lists()), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])]) with self.assertRaises(MultiValueDictKeyError) as cm: d.__getitem__('lastname') self.assertEqual(str(cm.exception), "'lastname'") self.assertIsNone(d.get('lastname')) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(sorted(d.values()), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual(sorted(list(six.iteritems(d))), [('name', 'Simon'), ('position', 'Developer')]) self.assertEqual(sorted(list(six.iterlists(d))), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])]) six.assertRaisesRegex(self, MultiValueDictKeyError, 'lastname', d.__getitem__, 'lastname') self.assertEqual(d.get('lastname'), None) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(sorted(list(six.itervalues(d))), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({ 'name': ['Adrian', 'Simon'], 'position': ['Developer'] }) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual(list(d.iteritems()), [('position', 'Developer'), ('name', 'Simon')]) self.assertEqual(list(d.iterlists()), [('position', ['Developer']), ('name', ['Adrian', 'Simon'])]) # MultiValueDictKeyError: "Key 'lastname' not found in # <MultiValueDict: {'position': ['Developer'], # 'name': ['Adrian', 'Simon']}>" self.assertRaisesMessage(MultiValueDictKeyError, '"Key \'lastname\' not found in <MultiValueDict: {\'position\':'\ ' [\'Developer\'], \'name\': [\'Adrian\', \'Simon\']}>"', d.__getitem__, 'lastname') self.assertEqual(d.get('lastname'), None) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(d.values(), ['Developer', 'Simon', 'Willison']) self.assertEqual(list(d.itervalues()), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({ 'name': ['Adrian', 'Simon'], 'position': ['Developer'] }) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual(sorted(list(six.iteritems(d))), [('name', 'Simon'), ('position', 'Developer')]) self.assertEqual(sorted(list(six.iterlists(d))), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])]) six.assertRaisesRegex(self, MultiValueDictKeyError, 'lastname', d.__getitem__, 'lastname') self.assertEqual(d.get('lastname'), None) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(sorted(list(six.itervalues(d))), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual( sorted(d.items()), [('name', 'Simon'), ('position', 'Developer')] ) self.assertEqual( sorted(d.lists()), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])] ) with self.assertRaisesMessage(MultiValueDictKeyError, 'lastname'): d.__getitem__('lastname') self.assertIsNone(d.get('lastname')) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(sorted(d.values()), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']}) self.assertEqual(d['name'], 'Simon') self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual(list(d.iteritems()), [('position', 'Developer'), ('name', 'Simon')]) self.assertEqual(list(d.iterlists()), [('position', ['Developer']), ('name', ['Adrian', 'Simon'])]) # MultiValueDictKeyError: "Key 'lastname' not found in # <MultiValueDict: {'position': ['Developer'], # 'name': ['Adrian', 'Simon']}>" self.assertRaisesMessage(MultiValueDictKeyError, '"Key \'lastname\' not found in <MultiValueDict: {\'position\':'\ ' [\'Developer\'], \'name\': [\'Adrian\', \'Simon\']}>"', d.__getitem__, 'lastname') self.assertEqual(d.get('lastname'), None) self.assertEqual(d.get('lastname', 'nonexistent'), 'nonexistent') self.assertEqual(d.getlist('lastname'), []) self.assertEqual(d.getlist('doesnotexist', ['Adrian', 'Simon']), ['Adrian', 'Simon']) d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) self.assertEqual(d.values(), ['Developer', 'Simon', 'Willison']) self.assertEqual(list(d.itervalues()), ['Developer', 'Simon', 'Willison'])
def test_multivaluedict(self): d = MultiValueDict({ "name": ["Adrian", "Simon"], "position": ["Developer"], "empty": [] }) self.assertEqual(d["name"], "Simon") self.assertEqual(d.get("name"), "Simon") self.assertEqual(d.getlist("name"), ["Adrian", "Simon"]) self.assertEqual( list(d.items()), [("name", "Simon"), ("position", "Developer"), ("empty", [])], ) self.assertEqual( list(d.lists()), [("name", ["Adrian", "Simon"]), ("position", ["Developer"]), ("empty", [])], ) with self.assertRaisesMessage(MultiValueDictKeyError, "'lastname'"): d.__getitem__("lastname") self.assertIsNone(d.get("empty")) self.assertEqual(d.get("empty", "nonexistent"), "nonexistent") self.assertIsNone(d.get("lastname")) self.assertEqual(d.get("lastname", "nonexistent"), "nonexistent") self.assertEqual(d.getlist("lastname"), []) self.assertEqual(d.getlist("doesnotexist", ["Adrian", "Simon"]), ["Adrian", "Simon"]) d.setlist("lastname", ["Holovaty", "Willison"]) self.assertEqual(d.getlist("lastname"), ["Holovaty", "Willison"]) self.assertEqual(list(d.values()), ["Simon", "Developer", [], "Willison"])
def test_multivaluedict(self): d = MultiValueDict({"name": ["Adrian", "Simon"], "position": ["Developer"]}) self.assertEqual(d["name"], "Simon") self.assertEqual(d.get("name"), "Simon") self.assertEqual(d.getlist("name"), ["Adrian", "Simon"]) self.assertEqual(sorted(list(six.iteritems(d))), [("name", "Simon"), ("position", "Developer")]) self.assertEqual(sorted(list(six.iterlists(d))), [("name", ["Adrian", "Simon"]), ("position", ["Developer"])]) # MultiValueDictKeyError: "Key 'lastname' not found in # <MultiValueDict: {'position': ['Developer'], # 'name': ['Adrian', 'Simon']}>" six.assertRaisesRegex( self, MultiValueDictKeyError, r'"Key \'lastname\' not found in <MultiValueDict', d.__getitem__, "lastname" ) self.assertEqual(d.get("lastname"), None) self.assertEqual(d.get("lastname", "nonexistent"), "nonexistent") self.assertEqual(d.getlist("lastname"), []) self.assertEqual(d.getlist("doesnotexist", ["Adrian", "Simon"]), ["Adrian", "Simon"]) d.setlist("lastname", ["Holovaty", "Willison"]) self.assertEqual(d.getlist("lastname"), ["Holovaty", "Willison"]) self.assertEqual(sorted(list(six.itervalues(d))), ["Developer", "Simon", "Willison"])
def qs_check_and_return(self, instance: MultiValueDict): try: res = {} for key, value in self.properties.items(): try: required = True if isinstance(value, Optional): required = False value = value.schema if not required and key not in instance: continue if isinstance(value, Array): res[key] = value.qs_check_and_return( instance.getlist(key)) else: res[key] = value.qs_check_and_return(instance.get(key)) except ConvertError as err: raise jsonschema.ValidationError(message=err.message, path=[key] + err.path) return res except jsonschema.ValidationError as err: raise DataError([err])
def test_multivaluedict(self): d = MultiValueDict({"name": ["Adrian", "Simon"], "position": ["Developer"]}) self.assertEqual(d["name"], "Simon") self.assertEqual(d.get("name"), "Simon") self.assertEqual(d.getlist("name"), ["Adrian", "Simon"]) self.assertEqual(sorted(list(six.iteritems(d))), [("name", "Simon"), ("position", "Developer")]) self.assertEqual(sorted(list(six.iterlists(d))), [("name", ["Adrian", "Simon"]), ("position", ["Developer"])]) six.assertRaisesRegex(self, MultiValueDictKeyError, "lastname", d.__getitem__, "lastname") self.assertEqual(d.get("lastname"), None) self.assertEqual(d.get("lastname", "nonexistent"), "nonexistent") self.assertEqual(d.getlist("lastname"), []) self.assertEqual(d.getlist("doesnotexist", ["Adrian", "Simon"]), ["Adrian", "Simon"]) d.setlist("lastname", ["Holovaty", "Willison"]) self.assertEqual(d.getlist("lastname"), ["Holovaty", "Willison"]) self.assertEqual(sorted(list(six.itervalues(d))), ["Developer", "Simon", "Willison"])
def value_from_datadict(self, data, files, name): if isinstance(data, MultiValueDict): data = data.copy() for key, value in data.items(): # treat value as csv string: ?foo=1,2 # if isinstance(value, string_types): data[key] = [x.strip() for x in value.rstrip(',').split(',') if x] data = MultiValueDict(data) if not isinstance(data, MultiValueDict): values_list = data.getlist(name, data.getlist('%s[]' % name)) or [] else: values_list = data.get(name, []) # apparently its an array, so no need to process it's values as csv # ?foo=1&foo=2 -> data.getlist(foo) -> foo = [1, 2] # ?foo[]=1&foo[]=2 -> data.getlist(foo[]) -> foo = [1, 2] if len(values_list) > 0: ret = [x for x in values_list if x] else: ret = [] return list(set(ret))
class QueryStringManager(object): """ QueryStringManager can be used to automatically set filters on listing. We take idea from django.contrib.admin.views.main.ChangeList class, but without all admin functionality (less coupled principle) However, it implements foofield__id__in filters, for example, equivalent to: FooModel.objects.filter(category__id__in=[8,9]) Example of use, with a request like http://foo.com?category__id__in=9&category__id__in=8: >>> qsm = QueryStringManager(request) >>> qsm.get_params() <MultiValueDict: {'category__id__in': [u'9', u'8']}> >>> qsm.get_query_string() u'?category__id__in=9&category__id__in=8' >>> qsm.get_filters() <MultiValueDict: {'category__id__in': [u'9', u'8']}> You can then use it in a view with: def foo_listing(request, ...): qsm = QueryStringManager(request) queryset = FooModel.objects.all() queryset = queryset.filter(qsm.get_filters()) category_choices = Category.objects.filter(parent__isnull=True) render_to_response('foo_listing.html', {'queryset': queryset, 'qsm': qsm, 'category_choices': category_choices} ) And last, in template you can use cmsutils admin filters with: {% load modelfilters %} {% filter_for_model 'fooapp' 'foomodel' 'publish_date' %} {% filter_for_model 'fooapp' 'foomodel' 'category' category_choices %} """ def __init__(self, request, search_fields=[], page_var=PAGE_VAR, ignore_params=[]): self.params = MultiValueDict() self.filters = MultiValueDict() self.excluders = MultiValueDict() self.search_fields = MultiValueDict() self.page=None if request is None: return raw_filters = {} for key, l in request.GET.lists(): if key == page_var: self.page = l elif key.startswith('__') or key in ignore_params: # private arg continue elif key.endswith('_0') or key.endswith('_1'): if key.endswith('_0'): key_new, l_new = self._convert_filter_splitdatetime(request, key, l, '_0', raw_filters) elif key.endswith('_1'): key_new, l_new = self._convert_filter_splitdatetime(request, key, l, '_1', raw_filters) raw_filters[key_new] = l_new else: raw_filters[key] = l good_filters = self.sanitize_filters(raw_filters) for key, l in good_filters.items(): try: key = str(key) except UnicodeEncodeError: key = 'key_%s' % len(l) self._set_into_dict(self.params, key, l) if key in search_fields: self._set_into_dict(self.search_fields, key, l) elif u'not_' in key: self._set_into_dict(self.excluders, key, l) else: self._set_into_dict(self.filters, key, l) def sanitize_filters(self, filters): # hook to searchform return filters def _get_from_dict(self, multidict, key): if key.endswith(IN_LOOKUP): return multidict.getlist(str(key)) else: return multidict.get(str(key)) def _set_into_dict(self, multidict, key, value): if key.endswith(IN_LOOKUP): multidict.setlist(str(key), value) else: multidict[str(key)] = value[0] def _get_multidict_items(self, multidict): for k, l in multidict.lists(): for v in l: yield k, v def _convert_filter_splitdatetime(self, request, key, l, endswith, filters): key_new = key.replace(endswith, '') date = request.GET.get('%s_0' % key_new, '') hour = request.GET.get('%s_1' % key_new, '') if date and hour: value_new = '%s %s' %(date, hour) value_new = value_new.strip() return (key_new, [value_new]) return key, l def get_query_string(self, new_params=None, remove=None): if new_params is None: new_params = MultiValueDict() if remove is None: remove = [] p = self.params.copy() for r in remove: for k in p.keys(): if (k.startswith(r) and r.endswith('__')) or k==r: del p[k] if isinstance(new_params, MultiValueDict): new_params_items = new_params.lists() setter = p.setlist else: new_params_items = new_params.items() setter = p.__setitem__ for k, v in new_params_items: if k in p and v is None: del p[k] elif v is not None: setter(k, v) query_string_blocks = [] for k, l in p.lists(): query_string_blocks.append('&'.join([u'%s=%s' % (k, v) for v in l])) return mark_safe('?' + '&'.join(query_string_blocks).replace(' ', '%20')) def get_params(self): return self.params def get_params_items(self): return self._get_multidict_items(self.params) def get_search_fields(self): return self.search_fields def get_filters(self): filters = {} for key in self.filters.keys(): filters[key] = self._get_from_dict(self.filters, key) return self.sanitize_filters(filters) def get_excluders(self): excluders = {} for key in self.excluders.keys(): filter_key = key.replace('not_', '') excluders[filter_key] = self._get_from_dict(self.excluders, key) return self.sanitize_filters(excluders) def get_filters_items(self): return self._get_multidict_items(self.filters) def get_search_value(self, value): return self.search_fields.get(value, None) def get_page(self): return self.page def search_performed(self): return bool(self.filters) or bool(self.excluders) or bool(self.search_fields)
class QueryStringManager(object): """ QueryStringManager can be used to automatically set filters on listing. We take idea from django.contrib.admin.views.main.ChangeList class, but without all admin functionality (less coupled principle) However, it implements foofield__id__in filters, for example, equivalent to: FooModel.objects.filter(category__id__in=[8,9]) Example of use, with a request like http://foo.com?category__id__in=9&category__id__in=8: >>> qsm = QueryStringManager(request) >>> qsm.get_params() <MultiValueDict: {'category__id__in': [u'9', u'8']}> >>> qsm.get_query_string() u'?category__id__in=9&category__id__in=8' >>> qsm.get_filters() <MultiValueDict: {'category__id__in': [u'9', u'8']}> You can then use it in a view with: def foo_listing(request, ...): qsm = QueryStringManager(request) queryset = FooModel.objects.all() queryset = queryset.filter(qsm.get_filters()) category_choices = Category.objects.filter(parent__isnull=True) render_to_response('foo_listing.html', {'queryset': queryset, 'qsm': qsm, 'category_choices': category_choices} ) And last, in template you can use cmsutils admin filters with: {% load modelfilters %} {% filter_for_model 'fooapp' 'foomodel' 'publish_date' %} {% filter_for_model 'fooapp' 'foomodel' 'category' category_choices %} """ def __init__(self, request, search_fields=[], page_var=PAGE_VAR, ignore_params=[]): self.params = MultiValueDict() self.filters = MultiValueDict() self.excluders = MultiValueDict() self.search_fields = MultiValueDict() self.page = None if request is None: return raw_filters = {} for key, l in request.GET.lists(): if key == page_var: self.page = l elif key.startswith('__') or key in ignore_params: # private arg continue elif key.endswith('_0') or key.endswith('_1'): if key.endswith('_0'): key_new, l_new = self._convert_filter_splitdatetime( request, key, l, '_0', raw_filters) elif key.endswith('_1'): key_new, l_new = self._convert_filter_splitdatetime( request, key, l, '_1', raw_filters) raw_filters[key_new] = l_new else: raw_filters[key] = l for key, l in raw_filters.items(): try: key = str(key) except UnicodeEncodeError: key = 'key_%s' % len(l) self._set_into_dict(self.params, key, l) if key in search_fields: self._set_into_dict(self.search_fields, key, l) elif u'not_' in key: self._set_into_dict(self.excluders, key, l) else: self._set_into_dict(self.filters, key, l) def _get_from_dict(self, multidict, key): if key.endswith(IN_LOOKUP): return multidict.getlist(str(key)) else: return multidict.get(str(key)) def _set_into_dict(self, multidict, key, value): if key.endswith(IN_LOOKUP): multidict.setlist(str(key), value) else: multidict[str(key)] = value[0] def _get_multidict_items(self, multidict): for k, l in multidict.lists(): for v in l: yield k, v def _convert_filter_splitdatetime(self, request, key, l, endswith, filters): key_new = key.replace(endswith, '') date = request.GET.get('%s_0' % key_new, '') hour = request.GET.get('%s_1' % key_new, '') if date and hour: value_new = '%s %s' % (date, hour) value_new = value_new.strip() return (key_new, [value_new]) return key, l def get_query_string(self, new_params=None, remove=None): if new_params is None: new_params = MultiValueDict() if remove is None: remove = [] p = self.params.copy() for r in remove: for k in p.keys(): if (k.startswith(r) and r.endswith('__')) or k == r: del p[k] if isinstance(new_params, MultiValueDict): new_params_items = new_params.lists() setter = p.setlist else: new_params_items = new_params.items() setter = p.__setitem__ for k, v in new_params_items: if k in p and v is None: del p[k] elif v is not None: setter(k, v) query_string_blocks = [] for k, l in p.lists(): query_string_blocks.append('&'.join([u'%s=%s' % (k, v) for v in l])) return mark_safe('?' + '&'.join(query_string_blocks).replace(' ', '%20')) def get_params(self): return self.params def get_params_items(self): return self._get_multidict_items(self.params) def get_search_fields(self): return self.search_fields def get_filters(self): filters = {} for key in self.filters.keys(): filters[key] = self._get_from_dict(self.filters, key) return filters def get_excluders(self): excluders = {} for key in self.excluders.keys(): filter_key = key.replace('not_', '') excluders[filter_key] = self._get_from_dict(self.excluders, key) return excluders def get_filters_items(self): return self._get_multidict_items(self.filters) def get_search_value(self, value): return self.search_fields.get(value, None) def get_page(self): return self.page def search_performed(self): return bool(self.filters) or bool(self.excluders) or bool( self.search_fields)