Django表单字段验证器不会在模板中的字段上引发错误

时间:2018-06-02 11:22:51

标签: django

当日期字段的值小于当前日期(基于另一个SO答案(Django: How to set DateField to only accept Today & Future dates)时,尝试使用此(https://stackoverflow.com/a/22513989/8236733)SO帖子在模板中出现表单引发错误思想是通过表单字段验证器完成的(参见https://docs.djangoproject.com/en/2.0/ref/forms/validation/#cleaning-a-specific-field-attribute))。但是,在表单模板中输入所谓的无效值时,这似乎不起作用。

forms.py

import datetime

from django import forms

from .models import Post


class MyForm(forms.Form):
    title = forms.CharField(max_length=100, required=True, help_text='Give a title',
                            widget=forms.TextInput(attrs={'size': '50rem'}))
    post = forms.CharField(max_length=280, required=True,
                           widget=forms.Textarea(attrs={'rows': 5}))
    expire_date = forms.DateField(  
        widget=forms.TextInput(attrs=
        {
            'class':'datepicker', # to use jquery datepicker
        }),
        required=True
    )
    expire_time = forms.TimeField(
        input_formats=['%H:%M %p'],
        widget=forms.TextInput(attrs=
        {
            'class':'timepicker', # to use jquery timepicker
        }),
        required=True)

    class Meta:
        model = Post
        fields = ('title', 'post', 'expire_date', 'expire_time',)

    def clean_date(self): # see https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-a-specific-field-attribute
        date = self.cleaned_data['expire_date']
        print(date)
        if date < datetime.date.today():
            raise forms.ValidationError("The date cannot be in the past!")
        return date

相关模板代码

 <form method="post">
                {% csrf_token %}
                {% for field in listing_form %}
                <p>
                    {{ field.label_tag }}
                <div class="ui input">{{ field }}</div>
                {% if field.help_text %}
                <small class="ui inverted">{{ field.help_text }}</small>
                {% endif %}
                {% for error in field.errors %}
                <p style="color: red">{{ error }}</p>
                {% endfor %}
                </p>
                {% endfor %}
                <button class="ui inverted button" type="submit">submit</button>
                <div class="ui divider"></div>

                </small>
            </form>

尝试提交带有过去日期的此表单不会在teplate中引发任何错误,并且表单的is_valid()方法在后端视图中不会引发任何错误。

django的新手,我在这里缺少什么?我是否需要以某种方式将验证方法附加到特定字段?

1 个答案:

答案 0 :(得分:1)

显然,清除/验证特定表单字段的表单方法遵循特定的命名约定clean_<field name>非常重要。这在文档(https://docs.djangoproject.com/en/2.0/ref/forms/validation/#cleaning-a-specific-field-attribute)中隐式显示,但从未直接说明。更改原始帖子中表单类中的clean_...方法以获得以下代码似乎解决了问题。

class MyForm(forms.Form):
    ....
    expire_date = forms.DateField(  
        widget=forms.TextInput(attrs=
        {
            'class':'datepicker', # to use jquery datepicker
        }),
        required=True
    )
    ....
    class Meta:
        model = Post
        fields = ('title', 'post', 'expire_date', 'expire_time',)

    def clean_expire_date(self): 
                date = self.cleaned_data['expire_date']
                print(date)
                if date < datetime.date.today():
                    raise forms.ValidationError("The date cannot be in the past!")
                return date

如果有人知道文档中的哪个更明确地指定了这个命名约定,请告诉我。