如何向Django modelForm添加自定义验证?

时间:2014-11-08 21:58:38

标签: python django forms

我有以下Django模型。我的表单用于在时间表上输入时间,并且有start_time和end_time字段。我想添加一个自定义检查以确保start_time在end_time之前或之前,或者如果不提供某些反馈给用户,如果不是。我正在尝试创建一个自定义的干净方法,但我做错了。

(来自models.py的代码段)

class TimesheetEntry(Model):
    WORKED='worked'
    SICK='sick'
    VACATION='vacation'
    TIME_CHOICES=(
        (WORKED,'Worked'),
        (SICK,'Sick'),
        (VACATION,'Vacation'))

    timesheet = models.ForeignKey('Timesheet', related_name='entries')
    start_time = models.DateTimeField(default=datetime.datetime.now)
    end_time = models.DateTimeField(blank=True, null=True)

(来自forms.py的代码段)

class TimesheetEntryForm(forms.ModelForm):
    start_time = forms.DateTimeField(widget=forms.SplitDateTimeWidget())
    end_time = forms.DateTimeField(widget=forms.SplitDateTimeWidget())
    class Meta:
        model = TimesheetEntry
        exclude = ['timesheet']

    def clean(self, *args, **kwargs):
        super(TimesheetEntryForm, self).clean(*args, **kwargs)
        if self.fields['start_time'] >= self.fields['end_time']:
            raise ValidationError("Start Time should be less than End Time")

当我提交表单时(start_time是否小于或大于end_time,我奇怪地得到两个错误中的一个,没有明显的理由为什么它不会每次都给我相同的错误。它不会更新db,我可以反复尝试一遍又一遍地使用相同的数据提交相同的表格,并且会给我以下两个错误中的一个,概率大约为50%。我知道这是一个很大的难题,但我希望有人能发现我正在制作的明显错误,并帮助我弄清楚如何解决这个问题。

TypeError: argument of type 'NoneType' is not iterable

-OR -

NameError: global name 'ValidationError' is not defined

应该注意的是,通过从方法中删除clean()方法将停止错误并允许我输入新条目(包括导致负小时总数的那些 - 这是我试图解决的最终问题)

2 个答案:

答案 0 :(得分:0)

关于NameError,只需:

from django.core.exceptions import ValidationError

还有一个注意事项,而不是重写表单字段,请在表单元素中执行以下操作:

widgets = {
           'start_time': SplitDateTimeWidget(),
           'end_time': SplitDateTimeWidget(),
          }

最后,干净的方法看起来像这样:

def clean(self):
    cleaned_data = super(TimesheetEntryForm, self).clean()
    if cleaned_data.get('start_time') >= cleaned_data.get('end_time'):
        raise ValidationError("blah blah")

希望它有所帮助!

答案 1 :(得分:0)

两个错误:首先,您应该访问self.cleaned_data['start_time'](和end_time);第二,你需要参考forms.ValidationError

此外,它没有受到伤害,但实际上没有必要调用超级干净的方法。