Django 自定义字段验证器 vs. clean

Posted

技术标签:

【中文标题】Django 自定义字段验证器 vs. clean【英文标题】:Django custom field validator vs. clean 【发布时间】:2011-09-16 11:40:10 【问题描述】:

我想创建 TodayOrLaterDateField() 子类 DateField() 字段,因为我在很多地方都使用这种条件。该字段的目的是避免输入过去的日期。

最直接的方法是什么?我对验证器与清洁方法感到困惑。 我已经尝试过 clean() 但是在将值与 datetime.date.today() 进行比较时,我收到“将 unicode 对象与日期进行比较”错误。

我正在使用 Django 1.3

【问题讨论】:

显示出现错误的代码。 【参考方案1】:

验证器只验证,它们不返回改进的格式; Clean 方法既验证又返回(有时已修改)值。

我认为这里的方法是只使用带有验证器的 DateField 作为 DateField 的继承类,并设置 default_validators。

import datetime
from django.core import exceptions
from django.db import models
from django.utils.translation import ugettext_lazy as _

def validate_date_today_or_later(value):
    'Place this in validators.py and import it to keep your model a bit cleaner'
    if value < datetime.date.today():
        raise exceptions.ValidationError(_('Date must be today or later'))

class TodayOrLaterDateField(models.DateField):
    default_validators = [validate_date_today_or_later,]

编辑: 如果您只想在表单字段中而不是在整个应用中使用相同的验证器,也可以将其应用于表单字段。

【讨论】:

第一句话就说明了一切。谢谢 D4V360! 我不明白的是,在 django 的其他地方,validateclean 实际调用的时间和地点...... 我认为最后一部分实际上应该是:default_validators = models.DateField.append(validate_date_today_or_later) 这将包括现有的 DateField 验证器。【参考方案2】:

您可以扩展 models.DateField 并覆盖 to_python 方法。没有在 Django 1.3 上测试,但应该可以工作。

import datetime
from django.core import exceptions
from django.db import models

class TodayOrLaterDateField(models.DateField):
    def to_python(self, value):
        value = super(TodayOrLaterDateField, self).to_python(value)
        if value < datetime.date.today():
            raise exceptions.ValidationError(u'Date must be today or later')
        return value

【讨论】:

该条件仅适用于前端。管理员可以使用过去的日期,所以我不会在这里使用模型。 (是的,对不起,没有提到)。将尝试使用 to_python() 和子类化 forms.DateField。谢谢!

以上是关于Django 自定义字段验证器 vs. clean的主要内容,如果未能解决你的问题,请参考以下文章

验证器和clean_field方法之间的django区别

django 表单验证和字段验证

第九十二节 自定义验证字段的方法

即使缺少所需的值,Django 验证也会调用 clean()

is_valid() vs clean() django 表单

14_自定义验证表单字段