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


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

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
6 58

6 ответов:

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

вот часть Джанго.ядро.валидаторы вы можете найти интересные :)

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'|^"([1-0346-7!#-\[\]-7]|\[1-011346-7])*"' # 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 и использовать это в вашей функции, а еще лучше-import 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

и вот это Почта:: RFC822:: адрес regexp используется в PERL, если вам действительно нужно быть параноиком.

from django.core.exceptions import ValidationError
from django.core.validators import validate_email
try:
    validate_email("foo.bar@baz.qux")
except ValidationError as e:
    print "oops! wrong email"
else:
    print "hooray! email is valid"

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

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

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

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

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

me+valid@mydomain.example.net

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

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

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

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

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

re.матч('\Б элемент[\W.-]+@элемент [\W.-]+.\w{2,4}\b', email)

для этого:

re.матч(р\б элемент[\W.-]+@элемент [\W.-]+.\w{2,4}\b', email)

работает со мной.