Django中Model字段类型和类似验证器之间有什么区别?

时间:2012-03-03 14:04:18

标签: python django validation

EmailFieldvalidator_email之间有什么区别?使用它们是不是一个坏主意?

或者那些提供代码的人

import django.db import models
email = models.EmailField()

VS

import django.db import models
email = models.CharField( max_length=75, validators = validate_email )

在文档中,您似乎也可以在validators内使用forms,但如果您已在models.py中指定了验证限制,那么您不需要在forms中再次指定{1}},对吗?所以我似乎更好地处理models.py内的所有限制。

1 个答案:

答案 0 :(得分:3)

我认为差异非常小,但是你会违反DRY委托人,你可能不应该这样做,除非你有充分的理由去做。

如果你去代码库:

#django.db.fields.__init__.py

class EmailField(CharField):
    default_validators = [validators.validate_email]
    description = _("E-mail address")

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', 75)
        CharField.__init__(self, *args, **kwargs)

    def formfield(self, **kwargs):
        # As with CharField, this will cause email validation to be performed
        # twice.
        defaults = {
            'form_class': forms.EmailField,
        }
        defaults.update(kwargs)
        return super(EmailField, self).formfield(**defaults)

正如您所看到的,该模型继承自Charfield,因此在适当的情况下使用emailfield就不会丢失任何内容。此外,默认验证器是validate_email。此外,您还可以获得已为您定义的描述变量。最后,在后端,它已经为你设置了'75'的max_length。你当然可以通过以与创建CharField时相同的方式定义max_length来轻松地覆盖它。

你可以看到formfields()正在从django.forms返回forms.EmailField。

看着这个,你可以看到:

#django.forms.fields.py
class EmailField(CharField):
    default_error_messages = {
        'invalid': _(u'Enter a valid e-mail address.'),
    }
    default_validators = [validators.validate_email]

    def clean(self, value):
        value = self.to_python(value).strip()
        return super(EmailField, self).clean(value)

但是,您将丢失使用EmailField可能提供的任何默认值,例如“正确”错误消息和自定义clean()方法。

最后,虽然它看起来很小,但实际上已经为你做了很多工作。因此,一般情况下,除非您有充分的理由,否则不应违反DRY本金。

编辑:

关于第二个问题,您希望表单根据您关注的任何条件进行验证,因此当您调用form.is_valid()时,它会返回True / False,并生成相应的失败消息。否则,is_valid()将验证True,当模型进行保存时,它将无声地失败,这将很难追踪。