11

我目前EmailField在我的表单上使用默认属性。我遇到的问题是表单认为无效的电子邮件name@mail.56是有效的。我需要在这个领域实现自己的validators功能以使其正常工作吗?

我的印象是:

#models.py
email = models.EmailField(max_length=254, blank=False, unique=True,
        error_messages={'required': 'Please provide your email address.',
                        'unique': 'An account with this email exist.'},)

或拥有:

#forms.py
email = forms.EmailField()

将为我处理这种类型的验证,但似乎并非如此。

4

3 回答 3

19

实际上,name@mail.56email 是 django 的有效电子邮件EmailValidator,看不到错误:

>>> from django.core.validators import validate_email
>>> validate_email("name@mail.56")
>>>

Django (1.5.1) 使用以下正则表达式来验证电子邮件地址:

r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    # quoted-string, see also https://www.rfc-editor.org/rfc/rfc2822#section-3.2.5
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"'
    r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)$)'  # domain
    r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$'

它实际上遵循RFC2822标准。

如果您想name@mail.56在验证过程中失败,您可以创建自己的验证器,并将其添加到EmailField具有内置validate_email验证器的验证器中,如下所示:

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

def custom_validate_email(value):
    if <custom_check>:
        raise ValidationError('Email format is incorrect')
...
email = models.EmailField(max_length=254, blank=False, unique=True, validators=[validate_email, custom_validate_email)

而且,仅供参考,您可以随时在django 票务系统中提交票证或在 django IRC 频道 (irc://irc.freenode.net/django) 上询问问题。

另请参阅:编写验证器

希望有帮助。

于 2013-08-21T22:15:02.863 回答
7

您可以在此处查看使用的正则表达式。

我认为它不会丢弃 100% 的错误电子邮件。这就是为什么在文档中它说:

使用适度复杂的正则表达式验证给定值是有效的电子邮件地址。

我从中了解到的是,由于设计决策,它并没有进行完美的验证(这将是一个性能权衡)。

最后,我很确定您的示例name@mail.56 是有效的电子邮件。电子邮件地址的域部分可以是 IP(IPv4 和 IPv6)或主机名。有关该主题的更多信息,请参见此处

于 2013-08-21T22:15:26.453 回答
2

对于仅数据库级别的验证,您必须full_clean手动调用。

文档中的三个重要引用:

验证器的运行方式

有关验证器如何在表单中运行的更多信息,请参阅表单验证,以及验证对象以了解它们如何在模型中运行。请注意,当您保存模型时,验证器不会自动运行,但如果您使用的是 ModelForm,它将在表单中包含的任何字段上运行您的验证器。有关模型验证如何与表单交互的信息,请参阅 ModelForm 文档。

模型.clean_fields

full_clean() 执行的第二步是调用 Model.clean()。应该重写此方法以对您的模型执行自定义验证。

模型.full_clean

请注意,当您调用模型的 save() 方法时,不会自动调用 full_clean()。当您想为自己手动创建的模型运行一步模型验证时,您需要手动调用它。

from django.db import models


class MyTable(models.Model):
    email = models.EmailField(unique=True)

    def save(self, *args, **kwargs):
        super().full_clean()
        super().save(*args, **kwargs)
于 2017-12-05T13:33:08.933 回答