Kaydet (Commit) d68987ae authored tarafından Duncan Parkes's avatar Duncan Parkes Kaydeden (comit) Tim Graham

Fixed #22897 -- Made QueryDict query_string argument optional.

Now QueryDict() is equivalent to QueryDict('') or QueryDict(None).
üst 7f4e2ef1
...@@ -317,7 +317,7 @@ class QueryDict(MultiValueDict): ...@@ -317,7 +317,7 @@ class QueryDict(MultiValueDict):
_mutable = True _mutable = True
_encoding = None _encoding = None
def __init__(self, query_string, mutable=False, encoding=None): def __init__(self, query_string=None, mutable=False, encoding=None):
super(QueryDict, self).__init__() super(QueryDict, self).__init__()
if not encoding: if not encoding:
encoding = settings.DEFAULT_CHARSET encoding = settings.DEFAULT_CHARSET
......
...@@ -355,13 +355,16 @@ Methods ...@@ -355,13 +355,16 @@ Methods
:class:`QueryDict` implements all the standard dictionary methods because it's :class:`QueryDict` implements all the standard dictionary methods because it's
a subclass of dictionary. Exceptions are outlined here: a subclass of dictionary. Exceptions are outlined here:
.. method:: QueryDict.__init__(query_string, mutable=False, encoding=None) .. method:: QueryDict.__init__(query_string=None, mutable=False, encoding=None)
Instantiates a ``QueryDict`` object based on ``query_string``. Instantiates a ``QueryDict`` object based on ``query_string``.
>>> QueryDict('a=1&a=2&c=3') >>> QueryDict('a=1&a=2&c=3')
<QueryDict: {u'a': [u'1', u'2'], u'b': [u'1']}> <QueryDict: {u'a': [u'1', u'2'], u'b': [u'1']}>
If ``query_string`` is not passed in, the resulting ``QueryDict`` will be
empty (it will have no keys or values).
Most ``QueryDict``\ s you encounter, and in particular those at Most ``QueryDict``\ s you encounter, and in particular those at
``request.POST`` and ``request.GET``, will be immutable. If you are ``request.POST`` and ``request.GET``, will be immutable. If you are
instantiating one yourself, you can make it mutable by passing instantiating one yourself, you can make it mutable by passing
...@@ -370,6 +373,10 @@ a subclass of dictionary. Exceptions are outlined here: ...@@ -370,6 +373,10 @@ 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`.
.. versionchanged:: 1.8
In previous versions, ``query_string`` was a required positional argument.
.. 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,
...@@ -523,7 +530,7 @@ In addition, ``QueryDict`` has the following methods: ...@@ -523,7 +530,7 @@ In addition, ``QueryDict`` has the following methods:
Optionally, urlencode can be passed characters which Optionally, urlencode can be passed characters which
do not require encoding. For example:: do not require encoding. For example::
>>> q = QueryDict('', mutable=True) >>> q = QueryDict(mutable=True)
>>> q['next'] = '/a&b/' >>> q['next'] = '/a&b/'
>>> q.urlencode(safe='/') >>> q.urlencode(safe='/')
'next=/a%26b/' 'next=/a%26b/'
......
...@@ -215,6 +215,11 @@ Requests and Responses ...@@ -215,6 +215,11 @@ Requests and Responses
:exc:`~django.core.exceptions.SuspiciousOperation`, the response will be :exc:`~django.core.exceptions.SuspiciousOperation`, the response will be
rendered with a detailed error page. rendered with a detailed error page.
* The ``query_string`` argument of :class:`~django.http.QueryDict` is now
optional, defaulting to ``None``, so a blank ``QueryDict`` can now be
instantiated with ``QueryDict()`` instead of ``QueryDict(None)`` or
``QueryDict('')``.
Tests Tests
^^^^^ ^^^^^
......
...@@ -26,12 +26,15 @@ lazystr = lazy(force_text, six.text_type) ...@@ -26,12 +26,15 @@ lazystr = lazy(force_text, six.text_type)
class QueryDictTests(unittest.TestCase): class QueryDictTests(unittest.TestCase):
def test_create_with_no_args(self):
self.assertEqual(QueryDict(), QueryDict(str('')))
def test_missing_key(self): def test_missing_key(self):
q = QueryDict(str('')) q = QueryDict()
self.assertRaises(KeyError, q.__getitem__, 'foo') self.assertRaises(KeyError, q.__getitem__, 'foo')
def test_immutability(self): def test_immutability(self):
q = QueryDict(str('')) q = QueryDict()
self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar') self.assertRaises(AttributeError, q.__setitem__, 'something', 'bar')
self.assertRaises(AttributeError, q.setlist, 'foo', ['bar']) self.assertRaises(AttributeError, q.setlist, 'foo', ['bar'])
self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar']) self.assertRaises(AttributeError, q.appendlist, 'foo', ['bar'])
...@@ -41,11 +44,11 @@ class QueryDictTests(unittest.TestCase): ...@@ -41,11 +44,11 @@ class QueryDictTests(unittest.TestCase):
self.assertRaises(AttributeError, q.clear) self.assertRaises(AttributeError, q.clear)
def test_immutable_get_with_default(self): def test_immutable_get_with_default(self):
q = QueryDict(str('')) q = QueryDict()
self.assertEqual(q.get('foo', 'default'), 'default') self.assertEqual(q.get('foo', 'default'), 'default')
def test_immutable_basic_operations(self): def test_immutable_basic_operations(self):
q = QueryDict(str('')) q = QueryDict()
self.assertEqual(q.getlist('foo'), []) self.assertEqual(q.getlist('foo'), [])
if six.PY2: if six.PY2:
self.assertEqual(q.has_key('foo'), False) self.assertEqual(q.has_key('foo'), False)
...@@ -95,30 +98,30 @@ class QueryDictTests(unittest.TestCase): ...@@ -95,30 +98,30 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.urlencode(), 'foo=bar') self.assertEqual(q.urlencode(), 'foo=bar')
def test_urlencode(self): def test_urlencode(self):
q = QueryDict(str(''), mutable=True) q = QueryDict(mutable=True)
q['next'] = '/a&b/' q['next'] = '/a&b/'
self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F') self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F')
self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/') self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/')
q = QueryDict(str(''), mutable=True) q = QueryDict(mutable=True)
q['next'] = '/t\xebst&key/' q['next'] = '/t\xebst&key/'
self.assertEqual(q.urlencode(), 'next=%2Ft%C3%ABst%26key%2F') self.assertEqual(q.urlencode(), 'next=%2Ft%C3%ABst%26key%2F')
self.assertEqual(q.urlencode(safe='/'), 'next=/t%C3%ABst%26key/') self.assertEqual(q.urlencode(safe='/'), 'next=/t%C3%ABst%26key/')
def test_mutable_copy(self): def test_mutable_copy(self):
"""A copy of a QueryDict is mutable.""" """A copy of a QueryDict is mutable."""
q = QueryDict(str('')).copy() q = QueryDict().copy()
self.assertRaises(KeyError, q.__getitem__, "foo") self.assertRaises(KeyError, q.__getitem__, "foo")
q['name'] = 'john' q['name'] = 'john'
self.assertEqual(q['name'], 'john') self.assertEqual(q['name'], 'john')
def test_mutable_delete(self): def test_mutable_delete(self):
q = QueryDict(str('')).copy() q = QueryDict(mutable=True)
q['name'] = 'john' q['name'] = 'john'
del q['name'] del q['name']
self.assertFalse('name' in q) self.assertFalse('name' in q)
def test_basic_mutable_operations(self): def test_basic_mutable_operations(self):
q = QueryDict(str('')).copy() q = QueryDict(mutable=True)
q['name'] = 'john' q['name'] = 'john'
self.assertEqual(q.get('foo', 'default'), 'default') self.assertEqual(q.get('foo', 'default'), 'default')
self.assertEqual(q.get('name', 'default'), 'john') self.assertEqual(q.get('name', 'default'), 'john')
...@@ -210,7 +213,7 @@ class QueryDictTests(unittest.TestCase): ...@@ -210,7 +213,7 @@ class QueryDictTests(unittest.TestCase):
self.assertEqual(q.getlist('foo'), ['bar', '\ufffd']) self.assertEqual(q.getlist('foo'), ['bar', '\ufffd'])
def test_pickle(self): def test_pickle(self):
q = QueryDict(str('')) q = QueryDict()
q1 = pickle.loads(pickle.dumps(q, 2)) q1 = pickle.loads(pickle.dumps(q, 2))
self.assertEqual(q == q1, True) self.assertEqual(q == q1, True)
q = QueryDict(str('a=b&c=d')) q = QueryDict(str('a=b&c=d'))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment