验证Django SelectDateWidget

时间:2017-08-07 07:40:51

标签: django django-forms django-views

我的问题是我在Django Form中使用DateField,而在Date Field中我正在使用SelectDateWidget。现在我的表单中有一个Date字段,但是渲染时SelectDateWidget将其转换为3个选择字段,现在发布时使用is_valid检查表单我无法验证表单bcos表单只包含一个Date字段但是我得到了请求中的3个变量.POST。

所以我的问题是如何使用SelectDateWidget验证表单?

1 个答案:

答案 0 :(得分:0)

有点晚了,但我希望它有所帮助。我挣扎了一段时间。这是不使用USE_L10N的症状。如果您查看Select Date Widget的来源,您会看到value_from_datadict以下列格式返回日期:'%s-%s-%s' % (y, m, d),其中包含非零填充数字。所以你可以在那里做一些事情:

使用国际化

您可以通过设置设置来执行此操作:

USE_L10N = True

这将导致value_from_datadict尝试以您指定的第一种格式返回日期。

使您的日期字段接受返回的日期格式

使您的日期字段以返回的格式接受日期。根据Django 1.11的源代码,这似乎是%Y-%-m%-d。所以您的日期字段可能如下所示:

date_field = models.DateField(
    input_formats=['%Y-%-m%-d']
)

子类SelectDateWidget并覆盖返回值

您可以覆盖SelectDateWidget.value_from_datadict的返回值,以匹配您希望收到的日期格式。例如,如果您的预期日期格式为%d/%m/%Y,则可以使用以下内容覆盖:

class CustomSelectDateWidget(SelectDateWidget):
"""
Overwrites `SelectDateWidget` to provide the expected date format.
"""

def value_from_datadict(self, data, files, name):
    y = data.get(self.year_field % name)
    m = data.get(self.month_field % name)
    d = data.get(self.day_field % name)
    if y == m == d == "0":
        return None
    if y and m and d:
        if settings.USE_L10N:
            input_format = get_format('DATE_INPUT_FORMATS')[0]
            try:
                date_value = datetime.date(int(y), int(m), int(d))
            except ValueError:
                return '%02d/%02d/%02d' % (int(d), int(m), int(y))
            else:
                date_value = datetime_safe.new_date(date_value)
                return date_value.strftime(input_format)
        else:
            return '%02d/%02d/%02d' % (int(d), int(m), int(y))
    return data.get(name)