Django

Code

Changeset 5464

Show
Ignore:
Timestamp:
06/11/07 15:02:08 (1 year ago)
Author:
mtredinnick
Message:

unicode: Changed the way re-encoding of form field submission works so that
file uploads are no longer completely broken. Added tests for this as well.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/unicode/django/http/__init__.py

    r5461 r5464  
    44from urllib import urlencode 
    55from django.utils.datastructures import MultiValueDict 
    6 from django.utils.encoding import smart_str, iri_to_uri 
     6from django.utils.encoding import smart_str, iri_to_uri, force_unicode 
    77 
    88RESERVED_CHARS="!*'();:@&=+$,/?%#[]" 
     
    5050    def _set_encoding(self, val): 
    5151        """ 
    52         Sets the encoding used for GET/POST accesses. 
     52        Sets the encoding used for GET/POST accesses. If the GET or POST 
     53        dictionary has already been created it is removed and recreated on the 
     54        next access (so that it is decoded correctly). 
    5355        """ 
    5456        self._encoding = val 
    5557        if hasattr(self, '_get'): 
    56             self.GET.encoding = val 
     58            del self._get 
    5759        if hasattr(self, '_post'): 
    58             self.POST.encoding = val 
     60            del self._post 
    5961 
    6062    def _get_encoding(self): 
     
    114116        self._mutable = True 
    115117        for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True 
    116             self.appendlist(key, value
     118            self.appendlist(force_unicode(key, errors='replace'), force_unicode(value, errors='replace')
    117119        self._mutable = mutable 
    118120 
     
    121123            raise AttributeError, "This QueryDict instance is immutable" 
    122124 
    123     def __getitem__(self, key): 
    124         return str_to_unicode(MultiValueDict.__getitem__(self, key), self.encoding) 
    125  
    126125    def __setitem__(self, key, value): 
    127126        self._assert_mutable() 
     127        key = str_to_unicode(key, self.encoding) 
     128        value = str_to_unicode(value, self.encoding) 
    128129        MultiValueDict.__setitem__(self, key, value) 
    129130 
     
    131132        self._assert_mutable() 
    132133        super(QueryDict, self).__delitem__(key) 
    133  
    134     def get(self, key, default=None): 
    135         return str_to_unicode(MultiValueDict.get(self, key, default), self.encoding) 
    136134 
    137135    def __copy__(self): 
     
    149147        return result 
    150148 
    151     def getlist(self, key): 
    152         """ 
    153         Returns a copy of the list associated with "key". This isn't a 
    154         reference to the original list because this method converts all the 
    155         values to unicode (without changing the original). 
    156         """ 
    157         return [str_to_unicode(v, self.encoding) for v in MultiValueDict.getlist(self, key)] 
    158  
    159149    def setlist(self, key, list_): 
    160150        self._assert_mutable() 
     151        key = str_to_unicode(key, self.encoding) 
     152        list_ = [str_to_unicode(elt, self.encoding) for elt in list_] 
    161153        MultiValueDict.setlist(self, key, list_) 
    162154 
     
    169161    def appendlist(self, key, value): 
    170162        self._assert_mutable() 
     163        key = str_to_unicode(key, self.encoding) 
     164        value = str_to_unicode(value, self.encoding) 
    171165        MultiValueDict.appendlist(self, key, value) 
    172166 
    173167    def update(self, other_dict): 
    174168        self._assert_mutable() 
    175         MultiValueDict.update(self, other_dict) 
     169        f = lambda s: str_to_unicode(s, self.encoding) 
     170        d = dict([(f(k), f(v)) for k, v in other_dict.items()]) 
     171        MultiValueDict.update(self, d) 
    176172 
    177173    def pop(self, key, *args): 
    178174        self._assert_mutable() 
    179         val = MultiValueDict.pop(self, key, *args) 
    180         if isinstance(val, list): 
    181             return [str_to_unicode(v, self.encoding) for v in val] 
    182         return str_to_unicode(val, self.encoding) 
     175        return MultiValueDict.pop(self, key, *args) 
    183176 
    184177    def popitem(self): 
    185178        self._assert_mutable() 
    186         key, values = MultiValueDict.popitem(self) 
    187         return str_to_unicode(key, self.encoding), [str_to_unicode(v, self.encoding) for v in values] 
    188  
    189     def keys(self): 
    190         return [str_to_unicode(k, self.encoding) for k in MultiValueDict.keys(self)] 
    191  
    192     def values(self): 
    193         return [str_to_unicode(v, self.encoding) for v in MultiValueDict.values(self)] 
    194  
    195     def items(self): 
    196         return [(str_to_unicode(k, self.encoding), str_to_unicode(v, self.encoding)) for k, v in MultiValueDict.items(self)] 
    197  
    198     def lists(self): 
    199         return [(str_to_unicode(k, self.encoding), [str_to_unicode(v, self.encoding) for v in v_list]) for k, v_list in MultiValueDict.lists(self)] 
     179        return MultiValueDict.popitem(self) 
    200180 
    201181    def clear(self): 
     
    203183        MultiValueDict.clear(self) 
    204184 
    205     def setdefault(self, *args): 
    206         self._assert_mutable() 
    207         return MultiValueDict.setdefault(self, *args) 
     185    def setdefault(self, key, default=None): 
     186        self._assert_mutable() 
     187        key = str_to_unicode(key, self.encoding) 
     188        default = str_to_unicode(default, self.encoding) 
     189        return MultiValueDict.setdefault(self, key, default) 
    208190 
    209191    def copy(self): 
  • django/branches/unicode/django/test/client.py

    r5338 r5464  
    6969            lines.extend([ 
    7070                '--' + boundary, 
    71                 'Content-Disposition: form-data; name="%s"' % to_str(key), 
    72                 '', 
    73                 '--' + boundary, 
    74                 'Content-Disposition: form-data; name="%s_file"; filename="%s"' % (to_str(key), to_str(value.name)), 
     71                'Content-Disposition: form-data; name="%s"; filename="%s"' % (to_str(key), to_str(value.name)), 
    7572                'Content-Type: application/octet-stream', 
    7673                '', 
  • django/branches/unicode/tests/regressiontests/httpwrappers/tests.py

    r5310 r5464  
    1717 
    1818>>> q.get('foo', 'default') 
    19 u'default' 
     19'default' 
    2020 
    2121>>> q.getlist('foo') 
     
    104104 
    105105>>> q.get('foo', 'default') 
    106 u'default' 
     106'default' 
    107107 
    108108>>> q.get('name', 'default') 
     
    168168 
    169169>>> q.pop('foo', 'not there') 
    170 u'not there' 
     170'not there' 
    171171 
    172172>>> q.get('foo', 'not there') 
    173 u'not there' 
     173'not there' 
    174174 
    175175>>> q.setdefault('foo', 'bar') 
     
    202202Traceback (most recent call last): 
    203203... 
    204 MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {'foo': ['bar']}>" 
     204MultiValueDictKeyError: "Key 'bar' not found in <MultiValueDict: {u'foo': [u'bar']}>" 
    205205 
    206206>>> q['something'] = 'bar' 
     
    213213 
    214214>>> q.get('bar', 'default') 
    215 u'default' 
     215'default' 
    216216 
    217217>>> q.getlist('foo') 
     
    304304 
    305305>>> q.get('foo', 'default') 
    306 u'default' 
     306'default' 
    307307 
    308308>>> q.getlist('vote') 
  • django/branches/unicode/tests/regressiontests/test_client_regress/models.py

    r5241 r5464  
    55from django.test import Client, TestCase 
    66from django.core import mail 
     7import os 
    78 
    89class AssertTemplateUsedTests(TestCase): 
     
    163164            self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])") 
    164165 
     166class AssertFileUploadTests(TestCase): 
     167    def test_simple_upload(self): 
     168        fd = open(os.path.join(os.path.dirname(__file__), "views.py")) 
     169        post_data = { 
     170            'name': 'Ringo', 
     171            'file_field': fd, 
     172        } 
     173        response = self.client.post('/test_client_regress/file_upload/', post_data) 
     174        self.assertEqual(response.status_code, 200) 
  • django/branches/unicode/tests/regressiontests/test_client_regress/urls.py

    r5185 r5464  
    11from django.conf.urls.defaults import * 
    2 from django.views.generic.simple import redirect_to 
    32import views 
    43 
    54urlpatterns = patterns('', 
    65    (r'^no_template_view/$', views.no_template_view), 
     6    (r'^file_upload/$', views.file_upload_view), 
    77) 
  • django/branches/unicode/tests/regressiontests/test_client_regress/views.py

    r5185 r5464  
    11from django.core.mail import EmailMessage, SMTPConnection 
    2 from django.http import HttpResponse 
     2from django.http import HttpResponse, HttpResponseServerError 
    33from django.shortcuts import render_to_response 
    44 
     
    77    return HttpResponse("No template used") 
    88 
     9def file_upload_view(request): 
     10    """ 
     11    Check that a file upload can be updated into the POST dictionary without 
     12    going pear-shaped. 
     13    """ 
     14    form_data = request.POST.copy() 
     15    form_data.update(request.FILES) 
     16    if isinstance(form_data['file_field'], dict) and isinstance(form_data['name'], unicode): 
     17        return HttpResponse('') 
     18    else: 
     19        return HttpResponseServerError() 
     20