Django

Code

Ticket #6652: allow_clean_to_specify_the_wrong_field-with-docs.diff

File allow_clean_to_specify_the_wrong_field-with-docs.diff, 4.7 kB (added by mrts, 4 months ago)
  • django/newforms/util.py

    old new  
    5050        return repr([force_unicode(e) for e in self]) 
    5151 
    5252class ValidationError(Exception): 
    53     def __init__(self, message): 
     53    def __init__(self, message, field_name=None): 
    5454        """ 
    5555        ValidationError can be passed any object that can be printed (usually 
    5656        a string) or a list of objects. 
    5757        """ 
     58        self.field_name = field_name 
    5859        if isinstance(message, list): 
    5960            self.messages = ErrorList([smart_unicode(msg) for msg in message]) 
    6061        else: 
  • django/newforms/forms.py

    old new  
    238238        try: 
    239239            self.cleaned_data = self.clean() 
    240240        except ValidationError, e: 
    241             self._errors[NON_FIELD_ERRORS] = e.messages 
     241            self._errors[e.field_name or NON_FIELD_ERRORS] = e.messages 
    242242        if self._errors: 
    243243            delattr(self, 'cleaned_data') 
    244244 
  • tests/regressiontests/forms/forms.py

    old new  
    611611 
    612612Another way of doing multiple-field validation is by implementing the 
    613613Form's clean() method. If you do this, any ValidationError raised by that 
    614 method will not be associated with a particular field; it will have a 
    615 special-case association with the field named '__all__'. 
     614method either will not be associated with a particular field 
     615and will have a special-case association with the field named '__all__';  
     616or if you specify the invalid field explicitly by passing the 'field_name' 
     617parameter to the error constructor, it will be associated with the field in 
     618similar manner to clean_XXX(). 
    616619Note that in Form.clean(), you have access to self.cleaned_data, a dictionary of 
    617620all the fields/values that have *not* raised a ValidationError. Also note 
    618621Form.clean() is required to return a dictionary of all clean data. 
     
    652655{} 
    653656>>> f.cleaned_data 
    654657{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'} 
     658>>> class UserRegistration(Form): 
     659...    username = CharField(max_length=10) 
     660...    password1 = CharField(widget=PasswordInput) 
     661...    password2 = CharField(widget=PasswordInput) 
     662...    def clean(self): 
     663...        if self.cleaned_data.get('password1') and self.cleaned_data.get('password2') and self.cleaned_data['password1'] != self.cleaned_data['password2']: 
     664...            raise ValidationError(u'Please make sure your passwords match.', field_name = 'password2') 
     665...        return self.cleaned_data 
     666>>> f = UserRegistration(auto_id=False) 
     667>>> f.errors 
     668{} 
     669>>> f = UserRegistration({}, auto_id=False) 
     670>>> print f.as_table() 
     671<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr> 
     672<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr> 
     673<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr> 
     674>>> f.errors 
     675{'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']} 
     676>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False) 
     677>>> f.errors 
     678{'password2': [u'Please make sure your passwords match.']} 
     679>>> print f.as_table() 
     680<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr> 
     681<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr> 
     682<tr><th>Password2:</th><td><ul class="errorlist"><li>Please make sure your passwords match.</li></ul><input type="password" name="password2" value="bar" /></td></tr> 
     683>>> print f.as_ul() 
     684<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li> 
     685<li>Password1: <input type="password" name="password1" value="foo" /></li> 
     686<li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul>Password2: <input type="password" name="password2" value="bar" /></li> 
     687>>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) 
     688>>> f.errors 
     689{} 
     690>>> f.cleaned_data 
     691{'username': u'adrian', 'password1': u'foo', 'password2': u'foo'} 
    655692 
    656693# Dynamic construction ######################################################## 
    657694