Fixed #9089 -- Correctly handle list values in MultiValueDict instances when passed to django.utils.http.urlencode. Thanks, kratorius, guettli and obeattie.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16064 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jannis Leidel 2011-04-22 12:01:41 +00:00
parent 7d11c30994
commit f4be8bd53d
2 changed files with 34 additions and 1 deletions

View File

@ -6,6 +6,7 @@ import urllib
import urlparse import urlparse
from email.Utils import formatdate from email.Utils import formatdate
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import smart_str, force_unicode from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy from django.utils.functional import allow_lazy
@ -49,7 +50,9 @@ def urlencode(query, doseq=0):
unicode strings. The parameters are first case to UTF-8 encoded strings and unicode strings. The parameters are first case to UTF-8 encoded strings and
then encoded as per normal. then encoded as per normal.
""" """
if hasattr(query, 'items'): if isinstance(query, MultiValueDict):
query = query.lists()
elif hasattr(query, 'items'):
query = query.items() query = query.items()
return urllib.urlencode( return urllib.urlencode(
[(smart_str(k), [(smart_str(k),

View File

@ -1,5 +1,6 @@
from django.utils import http from django.utils import http
from django.utils import unittest from django.utils import unittest
from django.utils.datastructures import MultiValueDict
class TestUtilsHttp(unittest.TestCase): class TestUtilsHttp(unittest.TestCase):
@ -21,3 +22,32 @@ class TestUtilsHttp(unittest.TestCase):
self.assertFalse(http.same_origin('http://foo.com', 'http://foo.com.evil.com')) self.assertFalse(http.same_origin('http://foo.com', 'http://foo.com.evil.com'))
# Different port # Different port
self.assertFalse(http.same_origin('http://foo.com:8000', 'http://foo.com:8001')) self.assertFalse(http.same_origin('http://foo.com:8000', 'http://foo.com:8001'))
def test_urlencode(self):
# 2-tuples (the norm)
result = http.urlencode((('a', 1), ('b', 2), ('c', 3)))
self.assertEqual(result, 'a=1&b=2&c=3')
# A dictionary
result = http.urlencode({ 'a': 1, 'b': 2, 'c': 3})
acceptable_results = [
# Need to allow all of these as dictionaries have to be treated as
# unordered
'a=1&b=2&c=3',
'a=1&c=3&b=2',
'b=2&a=1&c=3',
'b=2&c=3&a=1',
'c=3&a=1&b=2',
'c=3&b=2&a=1'
]
self.assertTrue(result in acceptable_results)
# A MultiValueDict
result = http.urlencode(MultiValueDict({
'name': ['Adrian', 'Simon'],
'position': ['Developer']
}), doseq=True)
acceptable_results = [
# MultiValueDicts are similarly unordered
'name=Adrian&name=Simon&position=Developer',
'position=Developer&name=Adrian&name=Simon'
]
self.assertTrue(result in acceptable_results)