Checking validity of email in django/python
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
value = "[email protected]"
try:
validate_email(value)
except ValidationError as e:
print("bad email, details:", e)
else:
print("good email")
Ick, no, please, don't try to validate email addresses yourself. It's one of those things people never get right.
Your safest option, since you're already using Django, is to just take advantage of its form validation for email. Per the docs:
>>> from django import forms
>>> f = forms.EmailField()
>>> f.clean('[email protected]')
u'[email protected]'
>>> f.clean(u'[email protected]')
u'[email protected]'
>>> f.clean('invalid e-mail address')
...
ValidationError: [u'Enter a valid e-mail address.']
UPDATE 2017: the code below is 7 years old and was since modified, fixed and expanded. For anyone wishing to do this now, the correct code lives around here.
Here is part of django.core.validators you may find interesting :)
class EmailValidator(RegexValidator):
def __call__(self, value):
try:
super(EmailValidator, self).__call__(value)
except ValidationError, e:
# Trivial case failed. Try for possible IDN domain-part
if value and u'@' in value:
parts = value.split(u'@')
domain_part = parts[-1]
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
super(EmailValidator, self).__call__(u'@'.join(parts))
else:
raise
email_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
so if you don't want to use forms and form fields, you can import email_re
and use it in your function, or even better - import validate_email
and use it, catching possible ValidationError
.
def validateEmail( email ):
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
try:
validate_email( email )
return True
except ValidationError:
return False
And here is Mail::RFC822::Address regexp used in PERL, if you really need to be that paranoid.
You got it wrong, but it is a task that you can't do anyway. There is one and only one way to know if an RFC 2822 address is valid, and that is to send mail to it and get a response. Doing anything else doesn't improve the information content of your datum by even a fractional bit.
You also screw the human factor and acceptance property, for when you give validateEmail
my address of
[email protected]
and you tell me I've made an error, I tell your application goodbye.