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

Этот вопрос уже имеет ответ здесь:

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

\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
69
задан muntu 10 July 2010 в 03:21
поделиться

3 ответа

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::Address regexp, используемый в PERL, если вам действительно нужно быть таким параноиком.

149
ответ дан 24 November 2019 в 13:32
поделиться

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

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

me+valid@mydomain.example.net

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

7
ответ дан 24 November 2019 в 13:32
поделиться

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

Ваш самый безопасный вариант, поскольку вы уже используете 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.']
49
ответ дан 24 November 2019 в 13:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: