【问题标题】:Clean method on date fields in Django FormsDjango Forms中日期字段的清理方法
【发布时间】:2014-07-17 00:23:31
【问题描述】:

我需要覆盖我的 Django 表单的 clean() 方法来一起测试两个日期字段:一个 begin_date 和一个 end_date(结束日期晚于开始日期,开始日期晚于现在)。

问题是当这两个字段之一为空或无效时,我得到一个异常(KeyError)。我想要一个简单的错误表单,就像我用空字符域得到的一样。

我很确定会在这里找到答案:Django self.cleaned_data Keyerror 但我没有。

代码如下:

class MyForm(forms.Form):
    begin_date = forms.DateField()
    end_date = forms.DateField()
    #...

    def clean(self):

        cleaned_data = super(MyForm, self).clean()
        errors = []

        begin_date = cleaned_data['begin_date']
        end_date = cleaned_data['end_date']
        #...

        # Test 1
            if begin_date < date.today():
                errors.append(forms.ValidationError(
                "La date de début doit être postérieure à la date actuelle"))
        # Test 2
            if end_date < begin_date:
                errors.append(forms.ValidationError(
                "La date de fin doit être posétieure à la date de début"))

        if errors:
            raise forms.ValidationError(errors)

        return cleaned_data

【问题讨论】:

  • 你的cleaned_data = super(DealForm, self).clean() 好吗?因为类的名称是MyForm 而不是DealForm
  • 是的,抱歉,我已经更改了 SO 中的代码以使其变得简单(编辑确定)

标签: python django datetime


【解决方案1】:

怎么样

if all([d in cleaned_data for d in ['begin_date', 'end_date']]):
    # your code
else:
    raise forms.ValidationError("A start date and end date are required")

这会在尝试使用这两个值之前检查它们是否存在,如果缺少一个或两个值,则会返回适当的错误消息。

【讨论】:

  • 谢谢。但是,这不会处理 2014/13/56 之类的无效数据
【解决方案2】:

在 Django 中,当您调用 super(MyForm, self).clean() 时,超类仅在数据已经有效时才填充cleaned_data,这就是为什么在文档中使用get 方法(https://docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other)。

由于您不想一起比较日期时间对象,请使用此代码确保日期字段正确:

if 'begin_date' in cleaned_data.keys():
        begin_date = cleaned_data['begin_date']
    else:
        begin_date = None
        errors.append(forms.ValidationError(
            "Bad start date format or empty"))

【讨论】:

  • 我也在另一篇文章中看到了这个。但问题是cleaned_data.get('begin_date') 返回一个字符串(不是日期),然后我无法执行begin_date &lt; date.today() 之类的操作
  • 在这种情况下,您可以尝试先询问密钥是否存在 if 'begin_date' in cleaned_data.keys():,然后使用 cleaned_data['begin_date'] 尝试将字符串转换为日期时间,但我确定 clean_data 返回日期时间对象
  • 非常感谢,这正是我所需要的。让我编辑您的答案以添加代码,我会将其标记为已接受。再次感谢。
猜你喜欢
  • 2014-04-07
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2014-08-06
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多