Changeset 8525
- Timestamp:
- 08/24/08 19:32:32 (3 months ago)
- Files:
-
- django/trunk/django/forms/widgets.py (modified) (14 diffs)
- django/trunk/tests/regressiontests/forms/forms.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/forms/widgets.py
r8491 r8525 11 11 from itertools import chain 12 12 from django.conf import settings 13 from django.utils.datastructures import MultiValueDict 13 from django.utils.datastructures import MultiValueDict, MergeDict 14 14 from django.utils.html import escape, conditional_escape 15 15 from django.utils.translation import ugettext … … 36 36 else: 37 37 media_attrs = kwargs 38 38 39 39 self._css = {} 40 40 self._js = [] 41 41 42 42 for name in MEDIA_TYPES: 43 43 getattr(self, 'add_' + name)(media_attrs.get(name, None)) … … 46 46 # if media_attrs != {}: 47 47 # raise TypeError, "'class Media' has invalid attribute(s): %s" % ','.join(media_attrs.keys()) 48 48 49 49 def __unicode__(self): 50 50 return self.render() 51 51 52 52 def render(self): 53 53 return mark_safe(u'\n'.join(chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES]))) 54 54 55 55 def render_js(self): 56 56 return [u'<script type="text/javascript" src="%s"></script>' % self.absolute_path(path) for path in self._js] 57 57 58 58 def render_css(self): 59 59 # To keep rendering order consistent, we can't just iterate over items(). … … 62 62 media.sort() 63 63 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]] 66 66 for medium in media]) 67 67 68 68 def absolute_path(self, path): 69 69 if path.startswith(u'http://') or path.startswith(u'https://') or path.startswith(u'/'): … … 78 78 79 79 def add_js(self, data): 80 if data: 80 if data: 81 81 self._js.extend([path for path in data if path not in self._js]) 82 82 83 83 def add_css(self, data): 84 84 if data: … … 100 100 else: 101 101 base = Media() 102 103 # Get the media definition for this class 102 103 # Get the media definition for this class 104 104 definition = getattr(cls, 'Media', None) 105 105 if definition: … … 118 118 return base 119 119 return property(_media) 120 120 121 121 class MediaDefiningClass(type): 122 122 "Metaclass for classes that can have media definitions" 123 def __new__(cls, name, bases, attrs): 123 def __new__(cls, name, bases, attrs): 124 124 new_class = super(MediaDefiningClass, cls).__new__(cls, name, bases, 125 125 attrs) … … 127 127 new_class.media = media_property(new_class) 128 128 return new_class 129 129 130 130 class Widget(object): 131 131 __metaclass__ = MediaDefiningClass … … 251 251 252 252 def value_from_datadict(self, data, files, name): 253 if isinstance(data, MultiValueDict):253 if isinstance(data, (MultiValueDict, MergeDict)): 254 254 return data.getlist(name) 255 255 return data.get(name, None) … … 265 265 "File widgets take data from FILES, not POST" 266 266 return files.get(name, None) 267 267 268 268 def _has_changed(self, initial, data): 269 269 if data is None: … … 418 418 419 419 def value_from_datadict(self, data, files, name): 420 if isinstance(data, MultiValueDict):420 if isinstance(data, (MultiValueDict, MergeDict)): 421 421 return data.getlist(name) 422 422 return data.get(name, None) 423 423 424 424 def _has_changed(self, initial, data): 425 425 if initial is None: … … 538 538 else: 539 539 label_for = '' 540 540 541 541 cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 542 542 option_value = force_unicode(option_value) … … 612 612 def value_from_datadict(self, data, files, name): 613 613 return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)] 614 614 615 615 def _has_changed(self, initial, data): 616 616 if initial is None: … … 648 648 return media 649 649 media = property(_get_media) 650 650 651 651 class SplitDateTimeWidget(MultiWidget): 652 652 """ django/trunk/tests/regressiontests/forms/forms.py
r7987 r8525 541 541 </ul> 542 542 543 Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict 544 conveniently work with this. 543 Data for a MultipleChoiceField should be a list. QueryDict, MultiValueDict and 544 MergeDict (when created as a merge of MultiValueDicts) conveniently work with 545 this. 545 546 >>> data = {'name': 'Yesterday', 'composers': ['J', 'P']} 546 547 >>> f = SongForm(data) … … 554 555 >>> from django.utils.datastructures import MultiValueDict 555 556 >>> 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']))) 556 562 >>> f = SongForm(data) 557 563 >>> f.errors
