Django EmailField接受无效值

时间:2013-08-21 21:42:21

标签: django django-forms

我目前正在使用表单上的默认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()

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

3 个答案:

答案 0 :(得分:14)

事实上,name@mail.56电子邮件是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 http://tools.ietf.org/html/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 ticket system提交一张票,或者在django IRC频道上询问这个问题(irc://irc.freenode.net/django)。

另请参阅:Writing validators

希望有所帮助。

答案 1 :(得分:5)

您可以看到使用的正则表达式here

我认为它不会丢弃100%的错误电子邮件。这就是docs所说的原因:

  

使用a验证给定值是否为有效的电子邮件地址   中等复杂的正则表达式。

我从中理解的是,由于设计决策(它将是性能权衡),它没有做出完美的验证。

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

答案 2 :(得分:1)

对于仅限DB级别的验证,您必须手动调用full_clean

文档中的三个重要引文:

How validators are run

  

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

Model.clean_fields

  

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

Model.full_clean

  

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

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)