Проверка действительности электронной почты в django/python

Я написал функцию для добавления писем в базу новостей. Пока я не добавил проверку действительности отправленного письма, он работал безупречно. Теперь каждый раз, когда я получаю "Неправильную электронную почту" взамен. Кто-нибудь может увидеть какие-либо ошибки здесь? Используемое регулярное выражение:

\b[\w\.-][email protected][\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\.-][email protected][\w\.-]+\.\w{2,4}\b', email) != None:
            return 1
    return 0

Ответ 1

UPDATE 2017: код ниже 7 лет и был изменен, исправлен и расширен. Для тех, кто хочет сделать это сейчас, здесь находится правильный код: https://github.com/django/django/blob/master/django/core/validators.py#L168-L180

Вот часть 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

И вот Mail:: RFC822:: Адрес regexp, используемый в PERL, если вам действительно нужно быть параноиком.

Ответ 2

from django.core.exceptions import ValidationError
from django.core.validators import validate_email
try:
    validate_email("[email protected]")
except ValidationError as e:
    print "oops! wrong email"
else:
    print "hooray! email is valid"

Ответ 3

Ick, нет, пожалуйста, не пытайтесь самостоятельно проверять адреса электронной почты. Это одна из тех вещей, которые люди никогда не получают.

Самый безопасный вариант, поскольку вы уже используете Django, заключается в том, чтобы просто воспользоваться его проверкой формы для электронной почты. В документах (http://docs.djangoproject.com/en/dev/ref/forms/fields/):

>>> 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.']

Ответ 4

Вы ошибаетесь, но это задача, которую вы не можете сделать в любом случае. Существует один и только один способ узнать, действителен ли адрес RFC 2822, и это должно отправить ему письмо и получить ответ. Выполнение чего-либо еще не улучшает информационный контент вашей базы данных даже с помощью дробного бита.

Вы также ввергаете человеческий фактор и свойство принятия, поскольку, когда вы даете validateEmail мой адрес

[email protected]

и вы скажете мне, что я допустил ошибку, я прошу прощения вашего приложения.

Ответ 5

Измените свой код:

re.match('\ b [\ w.-] + @[\ w.-] +.\w {2,4}\b', email)

:

re.match(r '\ b [\ w.-] + @[\ w.-] +.\w {2,4}\b', email)

отлично работает со мной.

Ответ 6

Это регулярное выражение будет проверять адрес электронной почты с разумной точностью.

\w[\w\.-]*@\w[\w\.-]+\.\w+

Он позволяет буквенно-цифровые символы, _, . и -.