Menu
CoddyTech

检查两个字段

本课属于 Coddy Django 学习旅程的“表单”单元。第 11 课,共 20 课。

冬季书展持续 3 天,结束日期不能早于开始日期。clean_<field> 方法只检查一个字段,因此跨字段的规则要写在 clean() 中,它会在每个字段完成自己的检查后运行。以下是一个预订表单示例,团体人数超过 6 人时必须填写电话号码:

def clean(self):
    cleaned_data = super().clean()
    guests = cleaned_data.get("guests")
    phone = cleaned_data.get("phone")
    if guests and guests > 6 and not phone:
        raise forms.ValidationError("Groups over 6 need a phone number.")
    return cleaned_data

检查失败的字段不会出现在 cleaned_data 中,可选日期为空时值为 None,因此要用 .get() 读取,并且只在两个值都存在时进行比较。

在 clean() 中引发的错误属于整个表单,因此字段循环不会显示它。{{ form.non_field_errors }} 会显示它。

challenge icon

挑战

中等

为活动添加结束日期。

  1. 在 events/forms.py 中,向 EventForm 添加一个可选的 end_date 日期字段。编写 clean():当两个日期都存在且结束日期早于开始日期时,抛出 The event cannot end before it starts.。使用 .get() 读取日期。
  2. 在 new_event 中,也保存 end_date。
  3. 在 new_event.html 中,在循环上方显示 form.non_field_errors。

把结束日期设为早于开始日期,你就会看到这条消息。

亲手试试

import datetime

from django import forms


class EventForm(forms.Form):
    title = forms.CharField(max_length=100)
    date = forms.DateField()
    place = forms.CharField(max_length=100)
    description = forms.CharField(widget=forms.Textarea, required=False)
    capacity = forms.IntegerField(min_value=1)

    def clean_date(self):
        date = self.cleaned_data["date"]
        if date < datetime.date.today():
            raise forms.ValidationError("The date cannot be in the past.")
        return date
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

表单中的所有课

自己练习: Django 在线编辑器