Django表单字段验证程序未在模板中的字段上引发错误

Django表单字段验证程序未在模板中的字段上引发错误,django,Django,当一个日期字段的值小于当前日期时(根据另一个SO答案(),我认为这是通过表单字段验证器完成的,请参阅),尝试使用此()使表单在模板中出现错误。但是,当在表单模板中输入假定无效的值时,这似乎不起作用 forms.py: import datetime from django import forms from .models import Post class MyForm(forms.Form): title = forms.CharField(max_length=100, r

当一个日期字段的值小于当前日期时(根据另一个SO答案(),我认为这是通过表单字段验证器完成的,请参阅),尝试使用此()使表单在模板中出现错误。但是,当在表单模板中输入假定无效的值时,这似乎不起作用

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>
导入日期时间
来自django导入表单
从。模型导入后
类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(最大长度=280,必需=True,
widget=forms.Textarea(attrs={'rows':5}))
expire\u date=forms.DateField(
widget=forms.TextInput(属性=
{
'class':'datepicker',#使用jquery datepicker
}),
必需=真
)
expire\u time=forms.TimeField(
输入格式=['%H:%M%p'],
widget=forms.TextInput(属性=
{
'class':'timepicker',#使用jquery timepicker
}),
必需=真)
类元:
型号=员额
字段=('title','post','expire\u date','expire\u time',)
def清洁日期(自身):#参见https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-特定字段属性
日期=自清理的数据['expire\u date']
打印(日期)
如果日期
相关模板片段

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>

{%csrf_令牌%}
{列表中字段的%u形式%}

{{field.label_tag}
{{field}}
{%if field.help_text%}
{{field.help_text}
{%endif%}
{%字段中有错误。错误%}

{{error}

{%endfor%}

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


刚到django的人,我有什么遗漏吗?我是否需要以某种方式将验证方法附加到特定字段?

显然,用于清理/验证特定表单字段的表单方法必须遵循特定的命名约定
clean
。这在docs()中隐式显示,但从未明确说明。将原始帖子中表单类中的
clean\uu…
方法更改为具有以下代码似乎已修复了该问题

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
类MyForm(forms.Form):
....
expire\u date=forms.DateField(
widget=forms.TextInput(属性=
{
'class':'datepicker',#使用jquery datepicker
}),
必需=真
)
....
类元:
型号=员额
字段=('title','post','expire\u date','expire\u time',)
def清洁过期日期(自我):
日期=自清理的数据['expire\u date']
打印(日期)
如果日期

如果有人知道在文档中的什么地方更明确地指定了这种命名约定,请让我知道。

这在您链接到的页面中绝对明确地说明:“the
clean_389;()
方法在表单子类上被调用–其中
被替换为表单字段属性的名称…例如,如果您想验证名为
serialnumber
CharField
的内容是否唯一,
clean_serialnumber()
将是执行此操作的正确位置。”@DanielRoseman我认为,仅从文档来看,命名是否真正重要还不完全清楚。例如,文档中说“编写一个在recipients字段上运行的清理方法,如:
def clean\u recipients(self):
…”读到这里,我认为方法命名纯粹是为了简单起见(我不知道django在提交表单时是如何知道检查验证器的,但我并不认为函数的实际名称是关键(尽管现在回想起来,我可以看到另一个也知道答案的人是如何按照原样编写文档的))