Fixed #7233 -- Ensured that QueryDict classes are always unpicklable. This

problem only arose on some systems, since it depends upon the order in which
the attributes are pickled. Makes reliable testing kind of tricky.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8460 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-08-21 13:55:21 +00:00
parent c8c159cbba
commit f2477b6450
2 changed files with 41 additions and 15 deletions

View File

@ -128,6 +128,11 @@ class QueryDict(MultiValueDict):
Values retrieved from this class are converted from the given encoding Values retrieved from this class are converted from the given encoding
(DEFAULT_CHARSET by default) to unicode. (DEFAULT_CHARSET by default) to unicode.
""" """
# These are both reset in __init__, but is specified here at the class
# level so that unpickling will have valid values
_mutable = True
_encoding = None
def __init__(self, query_string, mutable=False, encoding=None): def __init__(self, query_string, mutable=False, encoding=None):
MultiValueDict.__init__(self) MultiValueDict.__init__(self)
if not encoding: if not encoding:
@ -136,12 +141,24 @@ class QueryDict(MultiValueDict):
from django.conf import settings from django.conf import settings
encoding = settings.DEFAULT_CHARSET encoding = settings.DEFAULT_CHARSET
self.encoding = encoding self.encoding = encoding
self._mutable = True
for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True
self.appendlist(force_unicode(key, encoding, errors='replace'), self.appendlist(force_unicode(key, encoding, errors='replace'),
force_unicode(value, encoding, errors='replace')) force_unicode(value, encoding, errors='replace'))
self._mutable = mutable self._mutable = mutable
def _get_encoding(self):
if self._encoding is None:
# *Important*: do not import settings at the module level because
# of the note in core.handlers.modpython.
from django.conf import settings
self._encoding = settings.DEFAULT_CHARSET
return self._encoding
def _set_encoding(self, value):
self._encoding = value
encoding = property(_get_encoding, _set_encoding)
def _assert_mutable(self): def _assert_mutable(self):
if not self._mutable: if not self._mutable:
raise AttributeError("This QueryDict instance is immutable") raise AttributeError("This QueryDict instance is immutable")

View File

@ -392,17 +392,26 @@ u'\ufffd'
[u'bar', u'\ufffd'] [u'bar', u'\ufffd']
###################################### ########################
# HttpResponse with Unicode headers # # Pickling a QueryDict #
###################################### ########################
>>> import pickle
>>> r = HttpResponse() >>> q = QueryDict('a=b&c=d')
>>> q1 = pickle.loads(pickle.dumps(q))
>>> q == q1
True
######################################
# HttpResponse with Unicode headers #
######################################
>>> r = HttpResponse()
If we insert a unicode value it will be converted to an ascii If we insert a unicode value it will be converted to an ascii
string. This makes sure we comply with the HTTP specifications. string. This makes sure we comply with the HTTP specifications.
>>> r['value'] = u'test value' >>> r['value'] = u'test value'
>>> isinstance(r['value'], str) >>> isinstance(r['value'], str)
True True
An error is raised When a unicode object with non-ascii is assigned. An error is raised When a unicode object with non-ascii is assigned.
@ -411,10 +420,10 @@ An error is raised When a unicode object with non-ascii is assigned.
Traceback (most recent call last): Traceback (most recent call last):
... ...
UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format
The response also converts unicode keys to strings. The response also converts unicode keys to strings.
>>> r[u'test'] = 'testing key' >>> r[u'test'] = 'testing key'
>>> l = list(r.items()) >>> l = list(r.items())
>>> l.sort() >>> l.sort()
>>> l[1] >>> l[1]
@ -426,7 +435,7 @@ It will also raise errors for keys with non-ascii data.
Traceback (most recent call last): Traceback (most recent call last):
... ...
UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format
""" """
from django.http import QueryDict, HttpResponse from django.http import QueryDict, HttpResponse