provides support for query array notation

This commit is contained in:
Antoni Martyniuk 2016-11-05 01:59:55 +01:00
parent da3ed3be0a
commit 758dfd4750
2 changed files with 99 additions and 1 deletions

View File

@ -11,6 +11,7 @@ except:
from django import forms
from django.db.models.fields import BLANK_CHOICE_DASH
from django.forms.widgets import flatatt
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
from django.utils.six import string_types
@ -171,3 +172,29 @@ class BaseCSVWidget(forms.Widget):
class CSVWidget(BaseCSVWidget, forms.TextInput):
pass
class QueryArrayWidget(BaseCSVWidget, forms.TextInput):
"""
Enables request query array notation that might be consumed by MultipleChoiceFilter
1. Values can be provided as csv string: ?foo=bar,baz
2. Values can be provided as query array: ?foo[]=bar&foo[]=baz
"""
def value_from_datadict(self, data, files, name):
if not isinstance(data, MultiValueDict):
data = MultiValueDict(data)
request_data = data.getlist(name, data.getlist('%s[]' % name))
if isinstance(request_data, string_types):
request_data = [request_data]
if not request_data:
return []
extracted_data = set()
for item in request_data:
extracted_data.update([x.strip() for x in item.rstrip(',').split(',') if x])
return list(extracted_data)

View File

@ -4,7 +4,7 @@ from __future__ import unicode_literals
from django.test import TestCase
from django.forms import TextInput, Select
from django_filters.widgets import BooleanWidget
from django_filters.widgets import BooleanWidget, QueryArrayWidget
from django_filters.widgets import BaseCSVWidget
from django_filters.widgets import CSVWidget
from django_filters.widgets import RangeWidget
@ -279,3 +279,74 @@ class CSVSelectTests(TestCase):
self.assertHTMLEqual(w.render('price', [1, 2]), """
<input type="text" name="price" value="1,2" />""")
class QueryArrayWidgetTests(TestCase):
def test_widget_value_from_datadict(self):
w = QueryArrayWidget()
# Values can be provided as csv string: ?foo=bar,baz
data = {'price': None}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
data = {'price': '1'}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1'])
data = {'price': '1,2'}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1', '2'])
data = {'price': '1,,2'}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1', '2'])
data = {'price': '1,'}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1'])
data = {'price': ','}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
data = {'price': ''}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
result = w.value_from_datadict({}, {}, 'price')
self.assertEqual(result, [])
# Values can be provided as query array: ?foo[]=bar&foo[]=baz
data = {'price[]': None}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
data = {'price[]': ['1']}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1'])
data = {'price[]': ['1', '2']}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1', '2'])
data = {'price[]': ['1', '', '2']}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1', '2'])
data = {'price[]': ['1', '']}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, ['1'])
data = {'price[]': ['', '']}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
data = {'price[]': []}
result = w.value_from_datadict(data, {}, 'price')
self.assertEqual(result, [])
result = w.value_from_datadict({}, {}, 'price')
self.assertEqual(result, [])