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:
Adrian Holovaty 2005-09-02 19:39:47 +00:00
parent 92918b5ed7
commit 5bdf1da730
3 changed files with 29 additions and 11 deletions

View File

@ -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

View File

@ -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 {}

View File

@ -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
-------- --------