如何在Django中验证邮箱地址?

104 投票
7 回答
128962 浏览
提问于 2025-04-16 01:05

我写了一个函数,用来把电子邮件添加到新闻通讯的数据库里。在我添加了检查电子邮件有效性的功能之前,这个函数一直运行得很好。现在每次我都收到“错误的电子邮件”这样的反馈。有没有人能帮我看看哪里出错了?我用的正则表达式是:

\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b,这个表达式是100%有效的(http://gskinner.com/RegExr/),但我可能用错了,或者可能是逻辑上有问题:

def newsletter_add(request):
    if request.method == "POST":   
        try:
            e = NewsletterEmails.objects.get(email = request.POST['email'])
            message = _(u"Email is already added.")
            type = "error"
        except NewsletterEmails.DoesNotExist:
            if validateEmail(request.POST['email']):
                try:
                    e = NewsletterEmails(email = request.POST['email'])
                except DoesNotExist:
                    pass
                message = _(u"Email added.")
                type = "success"
                e.save()
            else:
                message = _(u"Wrong email")
                type = "error"

import re

def validateEmail(email):
    if len(email) > 6:
        if re.match('\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b', email) != None:
            return 1
    return 0

7 个回答

60

哎呀,不要自己去验证电子邮件地址。这个事情很多人都做不好。

既然你已经在用Django了,最安全的办法就是直接利用它的表单验证功能来处理电子邮件。根据文档

>>> from django import forms
>>> f = forms.EmailField()
>>> f.clean('foo@example.com')
u'foo@example.com'
>>> f.clean(u'foo@example.com')
u'foo@example.com'
>>> f.clean('invalid e-mail address')
...
ValidationError: [u'Enter a valid e-mail address.']
232

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这时候,很多人会去StackOverflow这个网站寻求帮助。在这个网站上,程序员们可以提问,也可以回答别人的问题。

当你在StackOverflow上提问时,最好能把你的问题描述得清楚明了。比如,你可以告诉大家你在做什么,遇到了什么具体的问题,出现了什么错误信息,以及你已经尝试过哪些解决办法。这样,其他人才能更好地理解你的问题,并给出有效的建议。

另外,看到别人提问时,如果你有解决办法,也可以分享你的经验。这样不仅能帮助到别人,还能让自己更深入地理解这个问题。

总之,StackOverflow是一个很好的学习和交流的平台,大家可以在这里互相帮助,共同进步。

from django.core.exceptions import ValidationError
from django.core.validators import validate_email

value = "foo.bar@baz.qux"

try:
    validate_email(value)
except ValidationError as e:
    print("bad email, details:", e)
else:
    print("good email")
172

更新于2017年: 下面的代码已经有7年历史,之后经过修改、修复和扩展。如果你现在想做这个,正确的代码可以在这里找到。

这里有一些你可能会觉得有趣的django.core.validators的内容 :)

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')

所以如果你不想使用表单和表单字段,你可以导入email_re并在你的函数中使用,或者更好的是 - 导入validate_email并使用它,同时捕获可能出现的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

这里还有一个在PERL中使用的Mail::RFC822::Address正则表达式,如果你真的需要这么谨慎的话。

撰写回答