Fixed #394 -- Trailing-slash redirects now retain duplicate name-value 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
This commit is contained in:
parent
92918b5ed7
commit
5bdf1da730
|
@ -4,7 +4,6 @@ from django.utils import httpwrappers
|
||||||
from django.core.mail import mail_managers
|
from django.core.mail import mail_managers
|
||||||
from django.views.core.flatfiles import flat_file
|
from django.views.core.flatfiles import flat_file
|
||||||
import md5, os
|
import md5, os
|
||||||
from urllib import urlencode
|
|
||||||
|
|
||||||
class CommonMiddleware:
|
class CommonMiddleware:
|
||||||
"""
|
"""
|
||||||
|
@ -49,7 +48,7 @@ class CommonMiddleware:
|
||||||
# Redirect
|
# Redirect
|
||||||
newurl = "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', new_url[0], new_url[1])
|
newurl = "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', new_url[0], new_url[1])
|
||||||
if request.GET:
|
if request.GET:
|
||||||
newurl += '?' + urlencode(request.GET)
|
newurl += '?' + request.GET.urlencode()
|
||||||
return httpwrappers.HttpResponseRedirect(newurl)
|
return httpwrappers.HttpResponseRedirect(newurl)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from Cookie import SimpleCookie
|
from Cookie import SimpleCookie
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
from urllib import urlencode
|
||||||
import datastructures
|
import datastructures
|
||||||
|
|
||||||
DEFAULT_MIME_TYPE = 'text/html'
|
DEFAULT_MIME_TYPE = 'text/html'
|
||||||
|
@ -117,6 +118,12 @@ class QueryDict(datastructures.MultiValueDict):
|
||||||
self.assert_synchronized()
|
self.assert_synchronized()
|
||||||
return self._keys
|
return self._keys
|
||||||
|
|
||||||
|
def urlencode(self):
|
||||||
|
output = []
|
||||||
|
for k, list_ in self.data.items():
|
||||||
|
output.extend([urlencode({k: v}) for v in list_])
|
||||||
|
return '&'.join(output)
|
||||||
|
|
||||||
def parse_cookie(cookie):
|
def parse_cookie(cookie):
|
||||||
if cookie == '':
|
if cookie == '':
|
||||||
return {}
|
return {}
|
||||||
|
|
|
@ -115,16 +115,20 @@ Methods
|
||||||
|
|
||||||
Example: ``"/music/bands/the_beatles/?print=true"``
|
Example: ``"/music/bands/the_beatles/?print=true"``
|
||||||
|
|
||||||
MultiValueDict objects
|
QueryDict objects
|
||||||
----------------------
|
-----------------
|
||||||
|
|
||||||
In an ``HttpRequest`` object, the ``GET`` and ``POST`` attributes are instances
|
In an ``HttpRequest`` object, the ``GET`` and ``POST`` attributes are instances
|
||||||
of ``django.utils.datastructures.MultiValueDict``. ``MultiValueDict`` is a
|
of ``django.utils.httpwrappers.QueryDict``. ``QueryDict`` is a dictionary-like
|
||||||
dictionary-like class customized to deal with multiple values for the same key.
|
class customized to deal with multiple values for the same key. This is
|
||||||
This is necessary because some HTML form elements, notably
|
necessary because some HTML form elements, notably ``<select multiple>``, pass
|
||||||
``<select multiple>``, pass multiple values for the same key.
|
multiple values for the same key.
|
||||||
|
|
||||||
``MultiValueDict`` implements the following standard dictionary methods:
|
``QueryDict`` instances are immutable, unless you create a ``copy()`` of them.
|
||||||
|
That means you can't change attributes of ``request.POST`` and ``request.GET``
|
||||||
|
directly.
|
||||||
|
|
||||||
|
``QueryDict`` implements the following standard dictionary methods:
|
||||||
|
|
||||||
* ``__repr__()``
|
* ``__repr__()``
|
||||||
|
|
||||||
|
@ -141,7 +145,11 @@ This is necessary because some HTML form elements, notably
|
||||||
|
|
||||||
* ``has_key(key)``
|
* ``has_key(key)``
|
||||||
|
|
||||||
* ``items()``
|
* ``items()`` -- Just like the standard dictionary ``items()`` method,
|
||||||
|
except this retains the order for values of duplicate keys, if any. For
|
||||||
|
example, if the original query string was ``"a=1&b=2&b=3"``, ``items()``
|
||||||
|
will return ``[("a", ["1"]), ("b", ["2", "3"])]``, where the order of
|
||||||
|
``["2", "3"]`` is guaranteed, but the order of ``a`` vs. ``b`` isn't.
|
||||||
|
|
||||||
* ``keys()``
|
* ``keys()``
|
||||||
|
|
||||||
|
@ -150,7 +158,8 @@ This is necessary because some HTML form elements, notably
|
||||||
In addition, it has the following methods:
|
In addition, it has the following methods:
|
||||||
|
|
||||||
* ``copy()`` -- Returns a copy of the object, using ``copy.deepcopy()``
|
* ``copy()`` -- Returns a copy of the object, using ``copy.deepcopy()``
|
||||||
from the Python standard library.
|
from the Python standard library. The copy will be mutable -- that is,
|
||||||
|
you can change its values.
|
||||||
|
|
||||||
* ``getlist(key)`` -- Returns the data with the requested key, as a Python
|
* ``getlist(key)`` -- Returns the data with the requested key, as a Python
|
||||||
list. Returns an empty list if the key doesn't exist.
|
list. Returns an empty list if the key doesn't exist.
|
||||||
|
@ -161,6 +170,9 @@ In addition, it has the following methods:
|
||||||
* ``appendlist(key, item)`` -- Appends an item to the internal list
|
* ``appendlist(key, item)`` -- Appends an item to the internal list
|
||||||
associated with key.
|
associated with key.
|
||||||
|
|
||||||
|
* ``urlencode()`` -- Returns a string of the data in query-string format.
|
||||||
|
Example: ``"a=2&b=3&b=5"``.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue