我目前正在使用表单上的默认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()
会为我处理这种类型的验证,但似乎并非如此。
答案 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
。
文档中的三个重要引文:
有关验证程序如何运行的详细信息,请参阅表单验证 在表单中,以及验证对象在模型中的运行方式。注意 保存模型时,验证程序不会自动运行, 但是如果您使用的是ModelForm,它将在任何上运行验证器 表单中包含的字段。请参阅ModelForm文档 有关模型验证如何与表单交互的信息。
full_clean()执行的第二步是调用Model.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)