Fixed #26707 -- Added QueryDict.fromkeys()

This commit is contained in:
wim glenn 2016-06-03 15:50:38 -07:00 committed by Tim Graham
parent da22079c21
commit 5ebebd1159
5 changed files with 64 additions and 2 deletions

View File

@ -771,6 +771,7 @@ answer newbie questions, and generally made Django that much better:
William Schwartz <wkschwartz@gmail.com> William Schwartz <wkschwartz@gmail.com>
Will Hardy <django@willhardy.com.au> Will Hardy <django@willhardy.com.au>
Wilson Miner <wminer@gmail.com> Wilson Miner <wminer@gmail.com>
Wim Glenn <hey@wimglenn.com>
wojtek wojtek
Xia Kai <http://blog.xiaket.org/> Xia Kai <http://blog.xiaket.org/>
Yann Fouillat <gagaro42@gmail.com> Yann Fouillat <gagaro42@gmail.com>

View File

@ -402,6 +402,19 @@ class QueryDict(MultiValueDict):
value) value)
self._mutable = mutable 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 @property
def encoding(self): def encoding(self):
if self._encoding is None: if self._encoding is None:

View File

@ -422,6 +422,16 @@ a subclass of dictionary. Exceptions are outlined here:
Strings for setting both keys and values will be converted from ``encoding`` 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`. 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) .. method:: QueryDict.__getitem__(key)
Returns the value for the given key. If the key has more than one value, Returns the value for the given key. If the key has more than one value,

View File

@ -187,7 +187,7 @@ Models
Requests and Responses Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
* ... * Added :meth:`QueryDict.fromkeys() <django.http.QueryDict.fromkeys>`.
Serialization Serialization
~~~~~~~~~~~~~ ~~~~~~~~~~~~~

View File

@ -25,7 +25,7 @@ from django.utils.encoding import force_str
from django.utils.functional import lazystr from django.utils.functional import lazystr
class QueryDictTests(unittest.TestCase): class QueryDictTests(SimpleTestCase):
def test_create_with_no_args(self): def test_create_with_no_args(self):
self.assertEqual(QueryDict(), QueryDict(str(''))) self.assertEqual(QueryDict(), QueryDict(str('')))
@ -271,6 +271,44 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(copy.copy(q).encoding, 'iso-8859-15') self.assertEqual(copy.copy(q).encoding, 'iso-8859-15')
self.assertEqual(copy.deepcopy(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): class HttpResponseTests(unittest.TestCase):