Fixed #3114 -- newforms MultipleChoiceField now handles MultiValueDicts properly. Thanks for the patch, Honza Král

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4196 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-12-13 06:26:04 +00:00
parent 49f6d06c2f
commit 4add4e4272
3 changed files with 27 additions and 1 deletions

View File

@ -2,7 +2,7 @@
Form classes Form classes
""" """
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict, MultiValueDict
from django.utils.html import escape from django.utils.html import escape
from fields import Field from fields import Field
from widgets import TextInput, Textarea, HiddenInput from widgets import TextInput, Textarea, HiddenInput
@ -221,6 +221,8 @@ class BoundField(StrAndUnicode):
def _data(self): def _data(self):
"Returns the data for this BoundField, or None if it wasn't given." "Returns the data for this BoundField, or None if it wasn't given."
if self.field.widget.requires_data_list and isinstance(self.form.data, MultiValueDict):
return self.form.data.getlist(self.name)
return self.form.data.get(self.name, None) return self.form.data.get(self.name, None)
data = property(_data) data = property(_data)

View File

@ -9,6 +9,7 @@ __all__ = (
) )
from util import StrAndUnicode, smart_unicode from util import StrAndUnicode, smart_unicode
from django.utils.datastructures import MultiValueDict
from django.utils.html import escape from django.utils.html import escape
from itertools import chain from itertools import chain
@ -64,6 +65,7 @@ class Input(Widget):
type='radio', which are special). type='radio', which are special).
""" """
input_type = None # Subclasses must define this. input_type = None # Subclasses must define this.
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
if value is None: value = '' if value is None: value = ''
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
@ -146,6 +148,11 @@ class SelectMultiple(Widget):
output.append(u'</select>') output.append(u'</select>')
return u'\n'.join(output) return u'\n'.join(output)
def value_from_datadict(self, data, name):
if isinstance(data, MultiValueDict):
return data.getlist(name)
return data.get(name, None)
class RadioInput(StrAndUnicode): class RadioInput(StrAndUnicode):
"An object used by RadioFieldRenderer that represents a single <input type='radio'>." "An object used by RadioFieldRenderer that represents a single <input type='radio'>."
def __init__(self, name, value, attrs, choice, index): def __init__(self, name, value, attrs, choice, index):

View File

@ -1672,6 +1672,23 @@ MultipleChoiceField can also be used with the CheckboxSelectMultiple widget.
<li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li> <li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
</ul> </ul>
Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict
conveniently work with this.
>>> data = {'name': 'Yesterday', 'composers': ['J', 'P']}
>>> f = SongForm(data)
>>> f.errors
{}
>>> from django.http import QueryDict
>>> data = QueryDict('name=Yesterday&composers=J&composers=P')
>>> f = SongForm(data)
>>> f.errors
{}
>>> from django.utils.datastructures import MultiValueDict
>>> data = MultiValueDict(dict(name='Yesterday', composers=['J', 'P']))
>>> f = SongForm(data)
>>> f.errors
{}
When using CheckboxSelectMultiple, the framework expects a list of input and When using CheckboxSelectMultiple, the framework expects a list of input and
returns a list of input. returns a list of input.
>>> f = SongForm({'name': 'Yesterday'}, auto_id=False) >>> f = SongForm({'name': 'Yesterday'}, auto_id=False)