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('' % '\n'.join(['
  • %s
  • ' % e for e in self.errors()[NON_FIELD_ERRORS]])) + output.append(u'' % 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('' % '\n'.join(['
  • %s
  • ' % e for e in bf.errors])) - output.append('%s:%s' % (pretty_name(name), bf)) + output.append(u'' % 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('
  • ' % '\n'.join(['
  • %s
  • ' % e for e in self.errors()[NON_FIELD_ERRORS]])) + output.append(u'
  • ' % 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 += '' % '\n'.join(['
  • %s
  • ' % e for e in bf.errors]) - line += '%s: %s' % (pretty_name(name), bf) + line += u'' % 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:\nLast name:\nBirthday:' +>>> 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()