tchaymore
tchaymore

Reputation: 3726

Problems raising custom validation error on Django form

I have a basic registration form that includes a BooleanField for people to accept Terms and Privacy Policy. What I want to do is change the language of the ValidationError that is raised if users do not check it.

class RegisterForm(forms.Form):
    username = forms.CharField(label="Username")
    email = forms.EmailField(label="Email")
    location = forms.CharField(label="Location",required=False)
    headline = forms.CharField(label="Headline",required=False)
    password = forms.CharField(widget=forms.PasswordInput,label="Password")
    confirm_password = forms.CharField(widget=forms.PasswordInput,label="Confirm Password")
    terms = TermsField(label=mark_safe("I have read and understand the <a href='/terms'>Terms of Service</a> and <a href='/privacy'>Privacy Policy</a>."),required=True)

TermsField is subclassed from BooleanField:

class TermsField(forms.BooleanField):
    "Check that user agreed, return custom message."

    def validate(self,value):
        if not value:
            raise forms.ValidationError('You must agree to the Terms of Service and Privacy Policy to use this site.')
        else:    
            super(TermsField, self).validate(value)

It validates correctly in that if a user does not check them TermsField the form does not validate, but it returns the generic "This field is required" error. This seems like a pretty simple task, and I'm sure I'm doing something basic wrong. Any ideas?

Upvotes: 2

Views: 2148

Answers (1)

orokusaki
orokusaki

Reputation: 57198

It's because Django sees the field is required and no value was provided, so it doesn't even bother calling your validate method (which comes after the built-in validation).

The way to accomplish what you're trying to accomplish is:

class RegisterForm(forms.Form):
    # ...other fields
    terms = forms.BooleanField(
        required=True,
        label=mark_safe('I have read and understand the <a href=\'/terms\'>Terms of Service</a> and <a href=\'/privacy\'>Privacy Policy</a>.')
        error_messages={'required': 'You must agree to the Terms of Service and Privacy Policy to use Prospr.me.'}
    )

That will override the default "required" message defined in Field.default_error_messages.

Upvotes: 5

Related Questions