Ticket #14809: 14809.3.diff

File 14809.3.diff, 2.8 KB (added by Chris Beaven, 13 years ago)

with tests for new QueryDict.urlencode behaviour

  • django/contrib/auth/views.py

    diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
    index 42ad68d..0325643 100644
    a b def redirect_to_login(next, login_url=None,  
    9999    if redirect_field_name:
    100100        querystring = QueryDict(login_url_parts[4], mutable=True)
    101101        querystring[redirect_field_name] = next
    102         login_url_parts[4] = querystring.urlencode()
     102        login_url_parts[4] = querystring.urlencode(safe='/')
    103103
    104104    return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))
    105105
  • django/http/__init__.py

    diff --git a/django/http/__init__.py b/django/http/__init__.py
    index 42027f0..0068519 100644
    a b import os  
    33import re
    44import time
    55from pprint import pformat
    6 from urllib import urlencode
     6from urllib import urlencode, quote
    77from urlparse import urljoin
    88try:
    99    from cStringIO import StringIO
    class QueryDict(MultiValueDict):  
    363363        """Returns a mutable copy of this object."""
    364364        return self.__deepcopy__({})
    365365
    366     def urlencode(self):
     366    def urlencode(self, safe=None):
     367        """
     368        Returns an encoded string of all query string arguments.
     369
     370        :arg safe: Used to specify characters which do not require quoting, for
     371            example::
     372
     373                >>> q = QueryDict('', mutable=True)
     374                >>> q['next'] = '/a&b/'
     375                >>> q.urlencode()
     376                'next=%2Fa%26b%2F'
     377                >>> q.urlencode(safe='/')
     378                'next=/a%26b/'
     379        """
    367380        output = []
     381        if safe:
     382            encode = lambda k, v: '%s=%s' % ((quote(k, safe), quote(v, safe)))
     383        else:
     384            encode = lambda k, v: urlencode({k: v})
    368385        for k, list_ in self.lists():
    369386            k = smart_str(k, self.encoding)
    370             output.extend([urlencode({k: smart_str(v, self.encoding)}) for v in list_])
     387            for value in list_:
     388                output.append(encode(k, smart_str(value, self.encoding)))
    371389        return '&'.join(output)
    372390
    373391class CompatCookie(SimpleCookie):
  • tests/regressiontests/httpwrappers/tests.py

    diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py
    index 6d45252..a744e6a 100644
    a b class QueryDictTests(unittest.TestCase):  
    7171
    7272        self.assertEqual(q.urlencode(), 'foo=bar')
    7373
     74    def test_urlencode(self):
     75        q = QueryDict('', mutable=True)
     76        q['next'] = '/a&b/'
     77        self.assertEqual(q.urlencode(), 'next=%2Fa%26b%2F')
     78        self.assertEqual(q.urlencode(safe='/'), 'next=/a%26b/')
     79
    7480    def test_mutable_copy(self):
    7581        """A copy of a QueryDict is mutable."""
    7682        q = QueryDict('').copy()
Back to Top