Skip to content

Commit

Permalink
Fixed #26707 -- Added QueryDict.fromkeys()
Browse files Browse the repository at this point in the history
  • Loading branch information
wimglenn authored and timgraham committed Jun 6, 2016
1 parent da22079 commit 5ebebd1
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ answer newbie questions, and generally made Django that much better:
William Schwartz <[email protected]>
Will Hardy <[email protected]>
Wilson Miner <[email protected]>
Wim Glenn <[email protected]>
wojtek
Xia Kai <http://blog.xiaket.org/>
Yann Fouillat <[email protected]>
Expand Down
13 changes: 13 additions & 0 deletions django/http/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,19 @@ def __init__(self, query_string=None, mutable=False, encoding=None):
value)
self._mutable = mutable

@classmethod
def fromkeys(cls, iterable, value='', mutable=False, encoding=None):
"""
Return a new QueryDict with keys (may be repeated) from an iterable and
values from value.
"""
q = cls('', mutable=True, encoding=encoding)
for key in iterable:
q.appendlist(key, value)
if not mutable:
q._mutable = False
return q

@property
def encoding(self):
if self._encoding is None:
Expand Down
10 changes: 10 additions & 0 deletions docs/ref/request-response.txt
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,16 @@ a subclass of dictionary. Exceptions are outlined here:
Strings for setting both keys and values will be converted from ``encoding``
to unicode. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`.

.. classmethod:: QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)

.. versionadded:: 1.11

Creates a new ``QueryDict`` with keys from ``iterable`` and each value
equal to ``value``. For example::

>>> QueryDict.fromkeys(['a', 'a', 'b'], value='val')
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>

.. method:: QueryDict.__getitem__(key)

Returns the value for the given key. If the key has more than one value,
Expand Down
2 changes: 1 addition & 1 deletion docs/releases/1.11.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ Models
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~

* ...
* Added :meth:`QueryDict.fromkeys() <django.http.QueryDict.fromkeys>`.

Serialization
~~~~~~~~~~~~~
Expand Down
40 changes: 39 additions & 1 deletion tests/httpwrappers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from django.utils.functional import lazystr


class QueryDictTests(unittest.TestCase):
class QueryDictTests(SimpleTestCase):
def test_create_with_no_args(self):
self.assertEqual(QueryDict(), QueryDict(str('')))

Expand Down Expand Up @@ -271,6 +271,44 @@ def test_non_default_encoding(self):
self.assertEqual(copy.copy(q).encoding, 'iso-8859-15')
self.assertEqual(copy.deepcopy(q).encoding, 'iso-8859-15')

def test_querydict_fromkeys(self):
self.assertEqual(QueryDict.fromkeys(['key1', 'key2', 'key3']), QueryDict('key1&key2&key3'))

def test_fromkeys_with_nonempty_value(self):
self.assertEqual(
QueryDict.fromkeys(['key1', 'key2', 'key3'], value='val'),
QueryDict('key1=val&key2=val&key3=val')
)

def test_fromkeys_is_immutable_by_default(self):
# Match behavior of __init__() which is also immutable by default.
q = QueryDict.fromkeys(['key1', 'key2', 'key3'])
with self.assertRaisesMessage(AttributeError, 'This QueryDict instance is immutable'):
q['key4'] = 'nope'

def test_fromkeys_mutable_override(self):
q = QueryDict.fromkeys(['key1', 'key2', 'key3'], mutable=True)
q['key4'] = 'yep'
self.assertEqual(q, QueryDict('key1&key2&key3&key4=yep'))

def test_duplicates_in_fromkeys_iterable(self):
self.assertEqual(QueryDict.fromkeys('xyzzy'), QueryDict('x&y&z&z&y'))

def test_fromkeys_with_nondefault_encoding(self):
key_utf16 = b'\xff\xfe\x8e\x02\xdd\x01\x9e\x02'
value_utf16 = b'\xff\xfe\xdd\x01n\x00l\x00P\x02\x8c\x02'
q = QueryDict.fromkeys([key_utf16], value=value_utf16, encoding='utf-16')
expected = QueryDict('', mutable=True)
expected['ʎǝʞ'] = 'ǝnlɐʌ'
self.assertEqual(q, expected)

def test_fromkeys_empty_iterable(self):
self.assertEqual(QueryDict.fromkeys([]), QueryDict(''))

def test_fromkeys_noniterable(self):
with self.assertRaises(TypeError):
QueryDict.fromkeys(0)


class HttpResponseTests(unittest.TestCase):

Expand Down

0 comments on commit 5ebebd1

Please sign in to comment.