验证模型表单日期字段时,Django 期望格式错误

Posted

技术标签:

【中文标题】验证模型表单日期字段时,Django 期望格式错误【英文标题】:Django expects wrong format when validating modelform datefield 【发布时间】:2021-09-18 03:40:11 【问题描述】:

我有一个页面,用户可以在其中输入dd/mm/yyyy 格式的一些日期。

在我的设置文件中,我有这个:

DATE_INPUT_FORMATS = ('%d/%m/%Y','%Y/%m/%d', '%Y-%m-%d',) 
USE_TZ = True
USE_L10N = True
TIME_ZONE = 'Europe/Rome

我使用django bootstrap4 datetime picker plus

该字段呈现如下:(我对屏幕截图表示歉意,我无法在没有转义的情况下复制 html,而且看起来非常混乱)

问题

问题是当我以 dd/mm/yyyy 格式输入日期时,它使用美国格式 (mm/dd/yyyy) 来验证它们。因此,如果我输入 27/12/2021,它将尝试保存 [2021 年第 12 天第 27 个月] 并且验证失败。防止保存表单集。

我不明白的是,当我设置了三个单独的 DATE_INPUT_FORMATS 并且它们都不是美国格式时,django 到底在哪里得到了它应该使用美国格式来验证日期的想法?

这里的图片显示页面上的日期以正确的格式收集

然后回复:['start_date': ['Enter a valid date.'], 'end_date': ['Enter a valid date.']]

表格

这就是我现在的位置:

class EducationForm(forms.ModelForm):

# def clean_start_date(self):
#     print(self.cleaned_data['start_date'])
#     return datetime.strptime((self.cleaned_data['start_date']), '%Y-%m-%d')
# def clean_end_date(self):
#     return datetime.strptime((self.cleaned_data['end_date']),  '%Y-%m-%d')

    class Meta:
        model = Education
        fields = ['start_date', 'end_date', 'institution', 'title']
        # localized_fields = ('start_date', 'end_date',)
        widgets = 
            'start_date': DatePickerInput(attrs=
                'data-provide' : 'datepicker',
                'class' : 'form-control my-date-picker',
                # 'data-date-format' : "DD/MM/YYYY"
            ,
            options=
                "format": "DD/MM/YYYY",
            ),
            'end_date': DatePickerInput(attrs=
                'placeholder': 'Ongoing',
                'data-provide' : 'datepicker',    
                'class' : 'form-control my-date-picker',           
                # 'data-date-format' : "DD/MM/YYYY"
            ,
            options=
                "format": "DD/MM/YYYY",
            ),

模板

在模板中没有什么特别的事情。我只是将日期时间字段呈现为 field 。

【问题讨论】:

我看到你有一个注释掉 localized_fields 行。您的设置中是否将USE_L10N 设置为true?如果是这样,这会改变日期格式行为。 那么,我没有立即看到任何错误。您是否能够验证视图接收到表单数据时的样子?或者确认DateFields 的input_formats 属性?我通常会尝试执行该 pdb 并直接通过 Django 进程运行服务器,如果我的环境足够简单以使其工作 - 如果没有额外的日志记录应该这样做,例如在您的视图中有一个额外的块。日期转换的代码非常简单易读:github.com/django/django/blob/main/django/forms/fields.py#L372 理论上,但您不需要重新排列字符串 - 只需验证它的格式是否符合您的预期。调试,而不是修复错误 - 问题是输入(由于未知原因)与日期字段对象所期望的格式不匹配,最好找出原因并直接修复它,使发送格式从表单与字段对象预期的解析格式一致。 从概念上讲,日期字段没有错。您在某处有错误 - 您的表单未提供您期望的格式,或者使用不正确的 input_format 值集创建了日期字段。第一步是找出是哪种情况,因此在您看来,记录request.POST['start_date']form.fields['start_date'].input_formats 之类的内容将使您确定问题所在。在您确切知道问题所在之前,您无法解决它。 嗯,input_formats 是一个序列是正常的,因此需要多个值,但您希望它是您的设置中给出的序列。这些看起来像默认列表的前几个值 (docs.djangoproject.com/en/dev/ref/settings/#date-input-formats) - 我会双重或三重检查设置字段名称中的拼写错误,否则会深入确保您的 Django 进程从该设置文件成功运行。 docs.djangoproject.com/en/dev/topics/settings/… 可能会有所帮助! 【参考方案1】:

最后,解决方案是将USE_L10N = False 添加到我的设置文件中。 看来除非指定,django 会忽略DATE_INPUT_FORMATS 的内容

【讨论】:

以上是关于验证模型表单日期字段时,Django 期望格式错误的主要内容,如果未能解决你的问题,请参考以下文章

Django使用不完整的模型创建一个有效的ModelForm,以在表单验证后手动添加字段

Django“自动对焦”表单验证错误

Django:模板中的 Crispy 表单验证错误

Django - 日期和时间字段说明

在自定义 Django 表单中验证和显示错误

13_表单的常用使用字段