Index: django/newforms/forms.py =================================================================== --- django/newforms/forms.py (revision 6917) +++ django/newforms/forms.py (working copy) @@ -195,8 +195,6 @@ self.cleaned_data = self.clean() except ValidationError, e: self._errors[NON_FIELD_ERRORS] = e.messages - if self._errors: - delattr(self, 'cleaned_data') def clean(self): """ @@ -293,6 +291,20 @@ """ return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name) data = property(_data) + + def _cleaned_data(self): + """ + Returns the cleaned_data for this BoundField, or raises KeyError if this field + lacks an entry in cleaned_data. + + Hint: If self.errors evaluates to False, we know this won't throw a + KeyError (otherwise, it will). + """ + try: + return self.form.cleaned_data[self.name] + except KeyError: + raise KeyError, "Field '%s' did not provide cleaned data." % self.name + cleaned_data = property(_cleaned_data) def label_tag(self, contents=None, attrs=None): """ Index: tests/modeltests/model_forms/models.py =================================================================== --- tests/modeltests/model_forms/models.py (revision 6917) +++ tests/modeltests/model_forms/models.py (working copy) @@ -235,9 +235,7 @@ >>> f.errors {'name': [u'This field is required.'], 'slug': [u'This field is required.']} >>> f.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'CategoryForm' object has no attribute 'cleaned_data' +{'url': u'foo'} >>> f.save() Traceback (most recent call last): ... Index: tests/regressiontests/forms/extra.py =================================================================== --- tests/regressiontests/forms/extra.py (revision 6917) +++ tests/regressiontests/forms/extra.py (working copy) @@ -396,4 +396,34 @@ >>> FormWithImage().is_multipart() True +################################### +# Test cleaned_data on BoundField # +################################### + +>>> class BandMemberForm(Form): +... name = CharField(max_length=20) +... plays_drums = BooleanField() + +>>> f = BandMemberForm({'name': 'Ringo', 'plays_drums': 'True'}) +>>> f.is_valid() +True +>>> f['name'].data +'Ringo' +>>> f['name'].cleaned_data +u'Ringo' +>>> f['plays_drums'].data +'True' +>>> f['plays_drums'].cleaned_data +True + +>>> f = BandMemberForm({'plays_drums': 'True'}) +>>> f.is_valid() +False +>>> f['name'].data +>>> f['name'].cleaned_data +Traceback (most recent call last): +... +KeyError: "Field 'name' did not provide cleaned data." +>>> f['plays_drums'].cleaned_data +True """ Index: tests/regressiontests/forms/forms.py =================================================================== --- tests/regressiontests/forms/forms.py (revision 6917) +++ tests/regressiontests/forms/forms.py (working copy) @@ -73,9 +73,7 @@ >>> p.is_valid() False >>> p.cleaned_data -Traceback (most recent call last): -... -AttributeError: 'Person' object has no attribute 'cleaned_data' +{} >>> print p