Ticket #3026: newforms_errors.patch

File newforms_errors.patch, 10.2 KB (added by Chris Beaven, 17 years ago)
  • django/newforms/forms.py

     
    2424    __metaclass__ = DeclarativeFieldsMetaclass
    2525
    2626    def __init__(self, data=None, auto_id=False): # TODO: prefix stuff
     27        self.ignore_errors = data is None
    2728        self.data = data or {}
    2829        self.auto_id = auto_id
    2930        self.clean_data = None # Stores the data after clean() has been called.
     
    4445            raise KeyError('Key %r not found in Form' % name)
    4546        return BoundField(self, field, name)
    4647
    47     def clean(self):
    48         if self.__errors is None:
    49             self.full_clean()
    50         return self.clean_data
    51 
    52     def errors(self):
     48    def _errors(self):
    5349        "Returns an ErrorDict for self.data"
    5450        if self.__errors is None:
    5551            self.full_clean()
    56         return self.__errors
     52        if self.ignore_errors:
     53            return ErrorDict()
     54        else:
     55            return self.__errors
     56    errors = property(_errors)
    5757
    5858    def is_valid(self):
    5959        """
    6060        Returns True if the form has no errors. Otherwise, False. This exists
    6161        solely for convenience, so client code can use positive logic rather
    62         than confusing negative logic ("if not form.errors()").
     62        than confusing negative logic ("if not form.errors").
    6363        """
    64         return not bool(self.errors())
     64        return not bool(self.errors)
    6565
    6666    def as_table(self):
    6767        "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
     
    7474    def as_table_with_errors(self):
    7575        "Returns this form rendered as HTML <tr>s, with errors."
    7676        output = []
    77         if self.errors().get(NON_FIELD_ERRORS):
     77        if self.errors.get(NON_FIELD_ERRORS):
    7878            # Errors not corresponding to a particular field are displayed at the top.
    79             output.append('<tr><td colspan="2"><ul>%s</ul></td></tr>' % '\n'.join(['<li>%s</li>' % e for e in self.errors()[NON_FIELD_ERRORS]]))
     79            output.append('<tr><td colspan="2"><ul>%s</ul></td></tr>' % '\n'.join(['<li>%s</li>' % e for e in self.errors[NON_FIELD_ERRORS]]))
    8080        for name, field in self.fields.items():
    8181            bf = BoundField(self, field, name)
    8282            if bf.errors:
     
    8787    def as_ul_with_errors(self):
    8888        "Returns this form rendered as HTML <li>s, with errors."
    8989        output = []
    90         if self.errors().get(NON_FIELD_ERRORS):
     90        if self.errors.get(NON_FIELD_ERRORS):
    9191            # Errors not corresponding to a particular field are displayed at the top.
    92             output.append('<li><ul>%s</ul></li>' % '\n'.join(['<li>%s</li>' % e for e in self.errors()[NON_FIELD_ERRORS]]))
     92            output.append('<li><ul>%s</ul></li>' % '\n'.join(['<li>%s</li>' % e for e in self.errors[NON_FIELD_ERRORS]]))
    9393        for name, field in self.fields.items():
    9494            bf = BoundField(self, field, name)
    9595            line = '<li>'
     
    149149        if there are none.
    150150        """
    151151        try:
    152             return self._form.errors()[self._name]
     152            return self._form.errors[self._name]
    153153        except KeyError:
    154154            return ErrorList()
    155155    errors = property(_errors)
  • tests/regressiontests/forms/tests.py

     
    879879...     first_name = CharField()
    880880...     last_name = CharField()
    881881...     birthday = DateField()
    882 >>> p = Person()
     882>>> p_new = Person()  # Not passed data, so no validation will take place.
     883>>> p = Person({})    # Even passing an empty dictionary will cause validation.
     884>>> print p_new
     885<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr>
     886<tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr>
     887<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr>
    883888>>> print p
     889<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    884890<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr>
     891<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    885892<tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr>
     893<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    886894<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr>
    887 >>> print p.as_table()
     895
     896>>> print p_new.as_table()
    888897<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr>
    889898<tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr>
    890899<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr>
    891 >>> print p.as_ul()
    892 <li>First name: <input type="text" name="first_name" /></li>
    893 <li>Last name: <input type="text" name="last_name" /></li>
    894 <li>Birthday: <input type="text" name="birthday" /></li>
    895 >>> print p.as_table_with_errors()
     900>>> print p.as_table()
    896901<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    897902<tr><td>First name:</td><td><input type="text" name="first_name" /></td></tr>
    898903<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    899904<tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr>
    900905<tr><td colspan="2"><ul><li>This field is required.</li></ul></td></tr>
    901906<tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr>
    902 >>> print p.as_ul_with_errors()
     907
     908>>> print p.as_ul()
     909<li>First name: <input type="text" name="first_name" /></li>
     910<li>Last name: <input type="text" name="last_name" /></li>
     911<li>Birthday: <input type="text" name="birthday" /></li>
     912>>> print p.as_ul()
    903913<li><ul><li>This field is required.</li></ul>First name: <input type="text" name="first_name" /></li>
    904914<li><ul><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li>
    905915<li><ul><li>This field is required.</li></ul>Birthday: <input type="text" name="birthday" /></li>
    906916
    907917>>> p = Person({'first_name': u'John', 'last_name': u'Lennon', 'birthday': u'1940-10-9'})
    908 >>> p.errors()
     918>>> p.errors
    909919{}
    910920>>> p.is_valid()
    911921True
    912 >>> p.errors().as_ul()
     922>>> p.errors.as_ul()
    913923u''
    914 >>> p.errors().as_text()
     924>>> p.errors.as_text()
    915925u''
    916926>>> p.clean()
    917927{'first_name': u'John', 'last_name': u'Lennon', 'birthday': datetime.date(1940, 10, 9)}
     
    932942<tr><td>Birthday:</td><td><input type="text" name="birthday" value="1940-10-9" /></td></tr>
    933943
    934944>>> p = Person({'last_name': u'Lennon'})
    935 >>> p.errors()
     945>>> p.errors
    936946{'first_name': [u'This field is required.'], 'birthday': [u'This field is required.']}
    937947>>> p.is_valid()
    938948False
    939 >>> p.errors().as_ul()
     949>>> p.errors.as_ul()
    940950u'<ul class="errorlist"><li>first_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>birthday<ul class="errorlist"><li>This field is required.</li></ul></li></ul>'
    941 >>> print p.errors().as_text()
     951>>> print p.errors.as_text()
    942952* first_name
    943953  * This field is required.
    944954* birthday
     
    11091119...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
    11101120...            raise ValidationError(u'Please make sure your passwords match.')
    11111121...        return self.clean_data['password2']
     1122
     1123Forms which are not passed any data will not contain error messages.
    11121124>>> f = UserRegistration()
    1113 >>> f.errors()
     1125>>> f.errors
     1126{}
     1127
     1128If you wish to receive error messages, pass the form an empty dictionary.
     1129>>> f = UserRegistration({})
     1130>>> f.errors
    11141131{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
     1132
    11151133>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'})
    1116 >>> f.errors()
     1134>>> f.errors
    11171135{'password2': [u'Please make sure your passwords match.']}
    11181136>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'})
    1119 >>> f.errors()
     1137>>> f.errors
    11201138{}
    11211139>>> f.clean()
    11221140{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
     
    11341152...        if self.clean_data.get('password1') and self.clean_data.get('password2') and self.clean_data['password1'] != self.clean_data['password2']:
    11351153...            raise ValidationError(u'Please make sure your passwords match.')
    11361154...        return self.clean_data
    1137 >>> f = UserRegistration()
     1155>>> f = UserRegistration({})
    11381156>>> print f.as_table()
    11391157<tr><td>Username:</td><td><input type="text" name="username" /></td></tr>
    11401158<tr><td>Password1:</td><td><input type="password" name="password1" /></td></tr>
    11411159<tr><td>Password2:</td><td><input type="password" name="password2" /></td></tr>
    1142 >>> f.errors()
     1160>>> f.errors
    11431161{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
    11441162>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'})
    1145 >>> f.errors()
     1163>>> f.errors
    11461164{'__all__': [u'Please make sure your passwords match.']}
    11471165>>> print f.as_table()
    1148 <tr><td>Username:</td><td><input type="text" name="username" value="adrian" /></td></tr>
    1149 <tr><td>Password1:</td><td><input type="password" name="password1" value="foo" /></td></tr>
    1150 <tr><td>Password2:</td><td><input type="password" name="password2" value="bar" /></td></tr>
    1151 >>> print f.as_table_with_errors()
    11521166<tr><td colspan="2"><ul><li>Please make sure your passwords match.</li></ul></td></tr>
    11531167<tr><td>Username:</td><td><input type="text" name="username" value="adrian" /></td></tr>
    11541168<tr><td>Password1:</td><td><input type="password" name="password1" value="foo" /></td></tr>
    11551169<tr><td>Password2:</td><td><input type="password" name="password2" value="bar" /></td></tr>
    1156 >>> print f.as_ul_with_errors()
     1170>>> print f.as_ul()
    11571171<li><ul><li>Please make sure your passwords match.</li></ul></li>
    11581172<li>Username: <input type="text" name="username" value="adrian" /></li>
    11591173<li>Password1: <input type="password" name="password1" value="foo" /></li>
    11601174<li>Password2: <input type="password" name="password2" value="bar" /></li>
    11611175>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'})
    1162 >>> f.errors()
     1176>>> f.errors
    11631177{}
    11641178>>> f.clean()
    11651179{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'}
Back to Top