summaryrefslogtreecommitdiff
path: root/django/newforms/forms.py
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2006-12-07 23:15:08 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2006-12-07 23:15:08 +0000
commitd87c354b65da2b1a3602bbd462f9b694e4519b8d (patch)
tree5d6e760655502b860befe1bd9f8041527e1c42b9 /django/newforms/forms.py
parent4542f21fc1b82dd0faa7be634640d2173339cb1e (diff)
generic-auth: Merged to trunk [4183].
git-svn-id: http://code.djangoproject.com/svn/django/branches/generic-auth@4184 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/newforms/forms.py')
-rw-r--r--django/newforms/forms.py96
1 files changed, 48 insertions, 48 deletions
diff --git a/django/newforms/forms.py b/django/newforms/forms.py
index 4bc6173249..e0b3d500b5 100644
--- a/django/newforms/forms.py
+++ b/django/newforms/forms.py
@@ -6,7 +6,7 @@ from django.utils.datastructures import SortedDict
from django.utils.html import escape
from fields import Field
from widgets import TextInput, Textarea, HiddenInput
-from util import ErrorDict, ErrorList, ValidationError
+from util import StrAndUnicode, ErrorDict, ErrorList, ValidationError
NON_FIELD_ERRORS = '__all__'
@@ -32,7 +32,7 @@ class DeclarativeFieldsMetaclass(type):
attrs['fields'] = SortedDictFromList(fields)
return type.__new__(cls, name, bases, attrs)
-class Form(object):
+class Form(StrAndUnicode):
"A collection of Fields, plus their associated data."
__metaclass__ = DeclarativeFieldsMetaclass
@@ -43,7 +43,7 @@ class Form(object):
self.clean_data = None # Stores the data after clean() has been called.
self.__errors = None # Stores the errors after clean() has been called.
- def __str__(self):
+ def __unicode__(self):
return self.as_table()
def __iter__(self):
@@ -72,41 +72,44 @@ class Form(object):
"""
return not self.ignore_errors and not bool(self.errors)
- def as_table(self):
- "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
- output = []
- if self.errors.get(NON_FIELD_ERRORS):
- # Errors not corresponding to a particular field are displayed at the top.
- output.append(u'<tr><td colspan="2">%s</td></tr>' % self.non_field_errors())
+ def _html_output(self, normal_row, error_row, row_ender, errors_on_separate_row):
+ "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
+ top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
+ output, hidden_fields = [], []
for name, field in self.fields.items():
bf = BoundField(self, field, name)
+ bf_errors = bf.errors # Cache in local variable.
if bf.is_hidden:
- if bf.errors:
- new_errors = ErrorList(['(Hidden field %s) %s' % (name, e) for e in bf.errors])
- output.append(u'<tr><td colspan="2">%s</td></tr>' % new_errors)
- output.append(str(bf))
+ if bf_errors:
+ top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors])
+ hidden_fields.append(unicode(bf))
else:
- if bf.errors:
- output.append(u'<tr><td colspan="2">%s</td></tr>' % bf.errors)
- output.append(u'<tr><td>%s</td><td>%s</td></tr>' % (bf.label_tag(escape(bf.verbose_name+':')), bf))
+ if errors_on_separate_row and bf_errors:
+ output.append(error_row % bf_errors)
+ output.append(normal_row % {'errors': bf_errors, 'label': bf.label_tag(escape(bf.verbose_name+':')), 'field': bf})
+ if top_errors:
+ output.insert(0, error_row % top_errors)
+ if hidden_fields: # Insert any hidden fields in the last row.
+ str_hidden = u''.join(hidden_fields)
+ if output:
+ last_row = output[-1]
+ # Chop off the trailing row_ender (e.g. '</td></tr>') and insert the hidden fields.
+ output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender
+ else: # If there aren't any rows in the output, just append the hidden fields.
+ output.append(str_hidden)
return u'\n'.join(output)
+ def as_table(self):
+ "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
+ return self._html_output(u'<tr><td>%(label)s</td><td>%(field)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', True)
+
def as_ul(self):
"Returns this form rendered as HTML <li>s -- excluding the <ul></ul>."
- output = []
- if self.errors.get(NON_FIELD_ERRORS):
- # Errors not corresponding to a particular field are displayed at the top.
- output.append(u'<li>%s</li>' % self.non_field_errors())
- for name, field in self.fields.items():
- bf = BoundField(self, field, name)
- if bf.is_hidden:
- if bf.errors:
- new_errors = ErrorList(['(Hidden field %s) %s' % (name, e) for e in bf.errors])
- output.append(u'<li>%s</li>' % new_errors)
- output.append(str(bf))
- else:
- output.append(u'<li>%s%s %s</li>' % (bf.errors, bf.label_tag(escape(bf.verbose_name+':')), bf))
- return u'\n'.join(output)
+ return self._html_output(u'<li>%(errors)s%(label)s %(field)s</li>', u'<li>%s</li>', '</li>', False)
+
+ def as_p(self):
+ "Returns this form rendered as HTML <p>s."
+ return self._html_output(u'<p>%(label)s %(field)s</p>', u'<p>%s</p>', '</p>', True)
def non_field_errors(self):
"""
@@ -155,18 +158,18 @@ class Form(object):
"""
return self.clean_data
-class BoundField(object):
+class BoundField(StrAndUnicode):
"A Field plus data"
def __init__(self, form, field, name):
- self._form = form
- self._field = field
- self._name = name
+ self.form = form
+ self.field = field
+ self.name = name
- def __str__(self):
+ def __unicode__(self):
"Renders this field as an HTML widget."
# Use the 'widget' attribute on the field to determine which type
# of HTML widget to use.
- value = 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
@@ -179,10 +182,7 @@ class BoundField(object):
Returns an ErrorList for this field. Returns an empty ErrorList
if there are none.
"""
- try:
- return self._form.errors[self._name]
- except KeyError:
- return ErrorList()
+ return self.form.errors.get(self.name, ErrorList())
errors = property(_errors)
def as_widget(self, widget, attrs=None):
@@ -190,7 +190,7 @@ class BoundField(object):
auto_id = self.auto_id
if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'):
attrs['id'] = auto_id
- return widget.render(self._name, self.data, attrs=attrs)
+ return widget.render(self.name, self.data, attrs=attrs)
def as_text(self, attrs=None):
"""
@@ -210,11 +210,11 @@ class BoundField(object):
def _data(self):
"Returns the data for this BoundField, or None if it wasn't given."
- return self._form.data.get(self._name, None)
+ return self.form.data.get(self.name, None)
data = property(_data)
def _verbose_name(self):
- return pretty_name(self._name)
+ return pretty_name(self.name)
verbose_name = property(_verbose_name)
def label_tag(self, contents=None):
@@ -224,7 +224,7 @@ class BoundField(object):
field's HTML-escaped verbose_name.
"""
contents = contents or escape(self.verbose_name)
- widget = self._field.widget
+ widget = self.field.widget
id_ = widget.attrs.get('id') or self.auto_id
if id_:
contents = '<label for="%s">%s</label>' % (widget.id_for_label(id_), contents)
@@ -232,7 +232,7 @@ class BoundField(object):
def _is_hidden(self):
"Returns True if this BoundField's widget is hidden."
- return self._field.widget.is_hidden
+ return self.field.widget.is_hidden
is_hidden = property(_is_hidden)
def _auto_id(self):
@@ -240,10 +240,10 @@ class BoundField(object):
Calculates and returns the ID attribute for this BoundField, if the
associated Form has specified auto_id. Returns an empty string otherwise.
"""
- auto_id = self._form.auto_id
+ auto_id = self.form.auto_id
if auto_id and '%s' in str(auto_id):
- return str(auto_id) % self._name
+ return str(auto_id) % self.name
elif auto_id:
- return self._name
+ return self.name
return ''
auto_id = property(_auto_id)