diff --git a/django/newforms/forms.py b/django/newforms/forms.py
index b8264fb6915..1422e0dd264 100644
--- a/django/newforms/forms.py
+++ b/django/newforms/forms.py
@@ -77,23 +77,23 @@ class Form(object):
def as_table(self):
"Returns this form rendered as HTML
s -- excluding the
."
- return u'\n'.join(['
%s:
%s
' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
+ return u'\n'.join([u'
%s:
%s
' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
def as_ul(self):
"Returns this form rendered as HTML
s -- excluding the
."
- return u'\n'.join(['
%s: %s
' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
+ return u'\n'.join([u'
%s: %s
' % (pretty_name(name), BoundField(self, field, name)) for name, field in self.fields.items()])
def as_table_with_errors(self):
"Returns this form rendered as HTML
s, with errors."
output = []
if self.errors().get(NON_FIELD_ERRORS):
# Errors not corresponding to a particular field are displayed at the top.
- output.append('
%s
' % '\n'.join(['
%s
' % e for e in self.errors()[NON_FIELD_ERRORS]]))
+ output.append(u'
%s
' % u'\n'.join([u'
%s
' % e for e in self.errors()[NON_FIELD_ERRORS]]))
for name, field in self.fields.items():
bf = BoundField(self, field, name)
if bf.errors:
- output.append('
%s
' % '\n'.join(['
%s
' % e for e in bf.errors]))
- output.append('
%s:
%s
' % (pretty_name(name), bf))
+ output.append(u'
%s
' % u'\n'.join([u'
%s
' % e for e in bf.errors]))
+ output.append(u'
%s:
%s
' % (pretty_name(name), bf))
return u'\n'.join(output)
def as_ul_with_errors(self):
@@ -101,13 +101,13 @@ class Form(object):
output = []
if self.errors().get(NON_FIELD_ERRORS):
# Errors not corresponding to a particular field are displayed at the top.
- output.append('
%s
' % '\n'.join(['
%s
' % e for e in self.errors()[NON_FIELD_ERRORS]]))
+ output.append(u'
%s
' % u'\n'.join([u'
%s
' % e for e in self.errors()[NON_FIELD_ERRORS]]))
for name, field in self.fields.items():
bf = BoundField(self, field, name)
- line = '
'
+ line = u'
'
if bf.errors:
- line += '
%s
' % '\n'.join(['
%s
' % e for e in bf.errors])
- line += '%s: %s' % (pretty_name(name), bf)
+ line += u'
%s
' % u'\n'.join([u'
%s
' % e for e in bf.errors])
+ line += u'%s: %s' % (pretty_name(name), bf)
output.append(line)
return u'\n'.join(output)
@@ -153,7 +153,13 @@ class BoundField(object):
"Renders this field as an HTML widget."
# Use the 'widget' attribute on the field to determine which type
# of HTML widget to use.
- return self.as_widget(self._field.widget)
+ value = self.as_widget(self._field.widget)
+ if not isinstance(value, basestring):
+ # Some Widget render() methods -- notably RadioSelect -- return a
+ # "special" object rather than a string. Call the __str__() on that
+ # object to get its rendered value.
+ value = value.__str__()
+ return value
def _errors(self):
"""
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index 73fa3c27bfc..0ef3e810fcd 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -955,6 +955,13 @@ u''
Last name:
Birthday:
+Unicode values are handled properly.
+>>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'})
+>>> p.as_table()
+u'
First name:
\n
Last name:
\n
Birthday:
'
+>>> p.as_ul()
+u'
First name:
\n
Last name:
\n
Birthday:
'
+
>>> p = Person({'last_name': u'Lennon'})
>>> p.errors()
{'first_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
@@ -1095,6 +1102,16 @@ For a form with a
+>>> class FrameworkForm(Form):
+... name = CharField()
+... language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=RadioSelect)
+>>> f = FrameworkForm()
+>>> print f['language']
+
+
+
+
+
MultipleChoiceField is a special case, as its data is required to be a list:
>>> class SongForm(Form):
... name = CharField()