Django

Code

Changeset 8525

Show
Ignore:
Timestamp:
08/24/08 19:32:32 (3 months ago)
Author:
mtredinnick
Message:

Fixed #7195 -- Fixed the validation of MultipleChoice? fields so that they can
be populated from request.REQUEST. Based on a patch from Daniel Roseman.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/forms/widgets.py

    r8491 r8525  
    1111from itertools import chain 
    1212from django.conf import settings 
    13 from django.utils.datastructures import MultiValueDict 
     13from django.utils.datastructures import MultiValueDict, MergeDict 
    1414from django.utils.html import escape, conditional_escape 
    1515from django.utils.translation import ugettext 
     
    3636        else: 
    3737            media_attrs = kwargs 
    38              
     38 
    3939        self._css = {} 
    4040        self._js = [] 
    41          
     41 
    4242        for name in MEDIA_TYPES: 
    4343            getattr(self, 'add_' + name)(media_attrs.get(name, None)) 
     
    4646        # if media_attrs != {}: 
    4747        #     raise TypeError, "'class Media' has invalid attribute(s): %s" % ','.join(media_attrs.keys()) 
    48          
     48 
    4949    def __unicode__(self): 
    5050        return self.render() 
    51          
     51 
    5252    def render(self): 
    5353        return mark_safe(u'\n'.join(chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES]))) 
    54          
     54 
    5555    def render_js(self): 
    5656        return [u'<script type="text/javascript" src="%s"></script>' % self.absolute_path(path) for path in self._js] 
    57          
     57 
    5858    def render_css(self): 
    5959        # To keep rendering order consistent, we can't just iterate over items(). 
     
    6262        media.sort() 
    6363        return chain(*[ 
    64             [u'<link href="%s" type="text/css" media="%s" rel="stylesheet" />' % (self.absolute_path(path), medium)  
    65                     for path in self._css[medium]]  
     64            [u'<link href="%s" type="text/css" media="%s" rel="stylesheet" />' % (self.absolute_path(path), medium) 
     65                    for path in self._css[medium]] 
    6666                for medium in media]) 
    67          
     67 
    6868    def absolute_path(self, path): 
    6969        if path.startswith(u'http://') or path.startswith(u'https://') or path.startswith(u'/'): 
     
    7878 
    7979    def add_js(self, data): 
    80         if data:     
     80        if data: 
    8181            self._js.extend([path for path in data if path not in self._js]) 
    82              
     82 
    8383    def add_css(self, data): 
    8484        if data: 
     
    100100        else: 
    101101            base = Media() 
    102          
    103         # Get the media definition for this class     
     102 
     103        # Get the media definition for this class 
    104104        definition = getattr(cls, 'Media', None) 
    105105        if definition: 
     
    118118            return base 
    119119    return property(_media) 
    120      
     120 
    121121class MediaDefiningClass(type): 
    122122    "Metaclass for classes that can have media definitions" 
    123     def __new__(cls, name, bases, attrs):             
     123    def __new__(cls, name, bases, attrs): 
    124124        new_class = super(MediaDefiningClass, cls).__new__(cls, name, bases, 
    125125                                                           attrs) 
     
    127127            new_class.media = media_property(new_class) 
    128128        return new_class 
    129          
     129 
    130130class Widget(object): 
    131131    __metaclass__ = MediaDefiningClass 
     
    251251 
    252252    def value_from_datadict(self, data, files, name): 
    253         if isinstance(data, MultiValueDict): 
     253        if isinstance(data, (MultiValueDict, MergeDict)): 
    254254            return data.getlist(name) 
    255255        return data.get(name, None) 
     
    265265        "File widgets take data from FILES, not POST" 
    266266        return files.get(name, None) 
    267      
     267 
    268268    def _has_changed(self, initial, data): 
    269269        if data is None: 
     
    418418 
    419419    def value_from_datadict(self, data, files, name): 
    420         if isinstance(data, MultiValueDict): 
     420        if isinstance(data, (MultiValueDict, MergeDict)): 
    421421            return data.getlist(name) 
    422422        return data.get(name, None) 
    423      
     423 
    424424    def _has_changed(self, initial, data): 
    425425        if initial is None: 
     
    538538            else: 
    539539                label_for = '' 
    540                  
     540 
    541541            cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 
    542542            option_value = force_unicode(option_value) 
     
    612612    def value_from_datadict(self, data, files, name): 
    613613        return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)] 
    614      
     614 
    615615    def _has_changed(self, initial, data): 
    616616        if initial is None: 
     
    648648        return media 
    649649    media = property(_get_media) 
    650      
     650 
    651651class SplitDateTimeWidget(MultiWidget): 
    652652    """ 
  • django/trunk/tests/regressiontests/forms/forms.py

    r7987 r8525  
    541541</ul> 
    542542 
    543 Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict 
    544 conveniently work with this. 
     543Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and 
     544MergeDict (when created as a merge of MultiValueDicts) conveniently work with 
     545this. 
    545546>>> data = {'name': 'Yesterday', 'composers': ['J', 'P']} 
    546547>>> f = SongForm(data) 
     
    554555>>> from django.utils.datastructures import MultiValueDict 
    555556>>> data = MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])) 
     557>>> f = SongForm(data) 
     558>>> f.errors 
     559{} 
     560>>> from django.utils.datastructures import MergeDict 
     561>>> data = MergeDict(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P']))) 
    556562>>> f = SongForm(data) 
    557563>>> f.errors