1

I'm creating a contact form (therefore not using a model-based form) and I've come across the following problem, after adding a regex validator to my email field: the custom error message I've added is now being displayed twice. This happens when I enter an email such as 'something' (it doesn't match my regex nor has the default '@' symbol - if I add the '@' symbol, only one message shows up).

I'm not sure, but I'm guessing django's default validation + my custom validation are responsible for that, so I'm wondering (if that's the problem), what I can do to prevent the same message from showing up twice.

Thank you in advance!

forms.py:

from django import forms
from django.core.validators import RegexValidator   

class ContactForm(forms.Form):
    full_name = forms.CharField(required=True)
    email = forms.EmailField(validators=[RegexValidator(regex=r'^\d+@([a-zA-Z0-9@-_]+)(\.[a-zA-Z0-9@-_]+)+\b')]
                            , error_messages={'invalid': 'This is my email error msg.'})
    message = forms.CharField(widget=forms.Textarea)

That 'This is my email error msg' is the one showing up repeatedly » eg: * This is my email error msg * This is my email error msg

views.py:

def contact(request):
    form = ContactForm(request.POST or None)
    context = {"form":form}

    if form.is_valid():
        form_name = form.cleaned_data.get("full_name")
        form_email = form.cleaned_data.get("email")
        form_message = form.cleaned_data.get("message")
        subject = "Message from %s (%s)" % (form_name, form_email)
        from_email = form_email
        to_email = ['myemail',]
        contact_message = form_message
        send_mail(subject, contact_message, from_email, to_email, fail_silently=False)
        context = {"form":form,"thanks_msg": "Thank you!"}

    return render(request, 'contact.html', context)

template:

<form action="" method="POST" class="form">  {% csrf_token %}
            {% for field in form %}
            <div class="fields-container">
                <label class="label">{{ field.label }}</label>
                {{ field }}
            </div> 
            <p class="server-form-errors"> {{ field.errors.as_text }} </p>
            {% endfor %}
            <button type="submit" id="form-button">Submit</button>
        </form>
Acla
  • 141
  • 3
  • 12
  • Possible duplicate of [Checking validity of email in django/python](http://stackoverflow.com/questions/3217682/checking-validity-of-email-in-django-python) – Sayse Mar 22 '16 at 16:00
  • Why not use the built in [EmailValidator](https://docs.djangoproject.com/en/1.9/ref/validators/#emailvalidator)? – Sayse Mar 22 '16 at 16:00
  • I'm looking at the topic you've posted but I can't find mentions about repeated validation messages, only different validation methods :S I'm going to look at the differences between regexvalidator and emailvalidator, but I think the problem will still be there because I get this double error message when my regex validation fails (that is, there's no match) and when I don't add the '@' symbol, so I believe that there are two validations kicking in but I only want one message when this happens. – Acla Mar 22 '16 at 16:11

1 Answers1

1

When you use a RegexValidator with an EmailField, Django checks the input twice, first with the built in validate_email validator, then with your validator. The second validator runs even if the first raises an error, therefore you can end up with multiple error messages.

One option would be to do your validation in the clean_email method. The clean_email method will only run if there are no errors from the email field's validator.

class ContactForm(forms.Form):
    full_name = forms.CharField(required=True)
    email = forms.EmailField(error_messages={'invalid': 'This is my email error msg.'})
    ...

    def clean_email(self):
        email = self.cleaned_data['email']
        validator = RegexValidator('...')
        validator(email)
        return email

Another option would be to subclass EmailField, and replace Django's email validator with your validator. Note that in this case, Django's email validator will not run, so it's up to you to make sure that your regex doesn't allow any invalid emails.

class MyEmailField(EmailField):
    default_validators = [RegexValidator(regex=r'...')]

class ContactForm(forms.Form):
    email = MyEmailField(error_messages={'invalid': 'This is my email error msg.'}))
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • Thank you so much for the explanation and examples! I've tried the first one and I got no repeated error messages! :) – Acla Mar 22 '16 at 16:56