Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #394 -- Trailing-slash redirects now retain duplicate name-valu…

…e query-string pairs, instead of the first of each pair. Added a QueryDict.urlencode() method to accomplish this. Updated the docs. Thanks for the good catch, mlambert

git-svn-id: http://code.djangoproject.com/svn/django/trunk@613 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5bdf1da730368a16beaa077d91457ff625f06bc4 1 parent 92918b5
Adrian Holovaty authored September 02, 2005
3  django/middleware/common.py
@@ -4,7 +4,6 @@
4 4
 from django.core.mail import mail_managers
5 5
 from django.views.core.flatfiles import flat_file
6 6
 import md5, os
7  
-from urllib import urlencode
8 7
 
9 8
 class CommonMiddleware:
10 9
     """
@@ -49,7 +48,7 @@ def process_request(self, request):
49 48
             # Redirect
50 49
             newurl = "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', new_url[0], new_url[1])
51 50
             if request.GET:
52  
-                newurl += '?' + urlencode(request.GET)
  51
+                newurl += '?' + request.GET.urlencode()
53 52
             return httpwrappers.HttpResponseRedirect(newurl)
54 53
 
55 54
         return None
7  django/utils/httpwrappers.py
... ...
@@ -1,5 +1,6 @@
1 1
 from Cookie import SimpleCookie
2 2
 from pprint import pformat
  3
+from urllib import urlencode
3 4
 import datastructures
4 5
 
5 6
 DEFAULT_MIME_TYPE = 'text/html'
@@ -117,6 +118,12 @@ def keys(self):
117 118
         self.assert_synchronized()
118 119
         return self._keys
119 120
 
  121
+    def urlencode(self):
  122
+        output = []
  123
+        for k, list_ in self.data.items():
  124
+            output.extend([urlencode({k: v}) for v in list_])
  125
+        return '&'.join(output)
  126
+
120 127
 def parse_cookie(cookie):
121 128
     if cookie == '':
122 129
         return {}
30  docs/request_response.txt
@@ -115,16 +115,20 @@ Methods
115 115
 
116 116
     Example: ``"/music/bands/the_beatles/?print=true"``
117 117
 
118  
-MultiValueDict objects
119  
-----------------------
  118
+QueryDict objects
  119
+-----------------
120 120
 
121 121
 In an ``HttpRequest`` object, the ``GET`` and ``POST`` attributes are instances
122  
-of ``django.utils.datastructures.MultiValueDict``. ``MultiValueDict`` is a
123  
-dictionary-like class customized to deal with multiple values for the same key.
124  
-This is necessary because some HTML form elements, notably
125  
-``<select multiple>``, pass multiple values for the same key.
  122
+of ``django.utils.httpwrappers.QueryDict``. ``QueryDict`` is a dictionary-like
  123
+class customized to deal with multiple values for the same key. This is
  124
+necessary because some HTML form elements, notably ``<select multiple>``, pass
  125
+multiple values for the same key.
126 126
 
127  
-``MultiValueDict`` implements the following standard dictionary methods:
  127
+``QueryDict`` instances are immutable, unless you create a ``copy()`` of them.
  128
+That means you can't change attributes of ``request.POST`` and ``request.GET``
  129
+directly.
  130
+
  131
+``QueryDict`` implements the following standard dictionary methods:
128 132
 
129 133
     * ``__repr__()``
130 134
 
@@ -141,7 +145,11 @@ This is necessary because some HTML form elements, notably
141 145
 
142 146
     * ``has_key(key)``
143 147
 
144  
-    * ``items()``
  148
+    * ``items()`` -- Just like the standard dictionary ``items()`` method,
  149
+      except this retains the order for values of duplicate keys, if any. For
  150
+      example, if the original query string was ``"a=1&b=2&b=3"``, ``items()``
  151
+      will return ``[("a", ["1"]), ("b", ["2", "3"])]``, where the order of
  152
+      ``["2", "3"]`` is guaranteed, but the order of ``a`` vs. ``b`` isn't.
145 153
 
146 154
     * ``keys()``
147 155
 
@@ -150,7 +158,8 @@ This is necessary because some HTML form elements, notably
150 158
 In addition, it has the following methods:
151 159
 
152 160
     * ``copy()`` -- Returns a copy of the object, using ``copy.deepcopy()``
153  
-      from the Python standard library.
  161
+      from the Python standard library. The copy will be mutable -- that is,
  162
+      you can change its values.
154 163
 
155 164
     * ``getlist(key)`` -- Returns the data with the requested key, as a Python
156 165
       list. Returns an empty list if the key doesn't exist.
@@ -161,6 +170,9 @@ In addition, it has the following methods:
161 170
     * ``appendlist(key, item)`` -- Appends an item to the internal list
162 171
       associated with key.
163 172
 
  173
+    * ``urlencode()`` -- Returns a string of the data in query-string format.
  174
+      Example: ``"a=2&b=3&b=5"``.
  175
+
164 176
 Examples
165 177
 --------
166 178
 

0 notes on commit 5bdf1da

Please sign in to comment.
Something went wrong with that request. Please try again.